SitePoint Sponsor

User Tag List

Results 1 to 16 of 16
  1. #1
    SitePoint Wizard
    Join Date
    Oct 2001
    Posts
    2,686
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    PHP and MySQL coding tips

    The great "PHP and MySQL coding tips" thread has been restructured. The posts from the old thread have been sorted into four categories and are quoted below, with a link to the original post. Not all posts have been quoted.

    Before you create a new tip, please make sure it's not already in here.

    Please do not create fluff posts. Instead of a thank you post here, send the person a Private Message (PM).

    It is Falesh that has done the heavy work here pulling the original thread apart. We would like to say a really big thank you for doing it. Great work! Send him a PM and say thanks!
    Last edited by longneck; Jun 27, 2008 at 11:55.

  2. #2
    SitePoint Wizard
    Join Date
    Oct 2001
    Posts
    2,686
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Strings



    As of PHP version 5.3.0 the POSIX Regular Expression functions have been Deprecated and should no longer be used.
    ereg_replace and eregi_replace
    ereg and eregi
    split and spliti
    sql_regcase
    http://php.net/manual/en/reference.p...tern.posix.php
    Differences from POSIX regex

    As of PHP 5.3.0, the POSIX Regex extension is deprecated. There are a number of differences between POSIX regex and PCRE regex. This page lists the most notable ones that are necessary to know when converting to PCRE.




    Quote Originally Posted by DR_LaRRY_PEpPeR View Post
    Strings
    1) As a finesse thing, I use single quotes around strings whenever possible (e.g. strings that don't contain variables, single quotes, \n, etc.). This is supposed to make less work for the PHP parser.

    2) When an array variable isn't in a string, put quotes around string-literal keys so they are not regarded as constants:

    PHP Code:
    // OK 
    echo $row[$key]; 

    // Wrong, unless key is a constant 
    echo $row[key]; 

    // Right 
    echo $row['key']; 

    // OK, since it's in a string 
    echo "Text: $row[key]"
    3) Remember, you can break out of PHP mode for large sections of HTML. This is faster than echo'ing and you don't need to escape quotes.
    Quote Originally Posted by Skunk View Post

    Personally I avoid any code that looks like this:

    PHP Code:
    $something 'this';
    $something .= 'and this';
    $something .= 'and this';
    $something .= 'and this';
    $something .= 'and this'
    or this:

    PHP Code:
    $something 'this'
    'and this'
    'and this'
    'and this'
    'and this'
    'and this'
    'and this'
    I much prefer the following:

    PHP Code:
    $something 'this
    and this
    and this
    and this'

    Why? Because in the first two examples PHP is having to allocate memory for multiple strings and then go through the (relatively) expensive process of "sticking" them together again. If you just declare a string over multiple lines you are avoiding that overhead. You have to be careful to make code readable if you do this but I've never had any problems with it.

    Here's a handy (relatively undocumented) tip. PHP supports the following method of assigning strings (borrowed from Perl):

    PHP Code:
    $string = <<<ENDOFSTRING
    This is a string

    It can include both 'single' and "double" quotes 
    without needing to escape them. However, 
    $variables
    will still be interpolated as they are in double 
    quoted strings. Complex variable expressions such as
    {$array['element']} or {$object->property} can also
    be included and will be evaluated if they are included
    in curly braces (they may work without curly braces
    but I tend to include them for added clarity). The
    string will terminate with whatever you specified
    at the start like this:
    ENDOFSTRING; 
    >>>>
    Falesh's comment:

    See php.net for more info.
    <<<<
    Quote Originally Posted by auroraeosrose View Post

    You can eek a bit more speed out of your code, especially if you have LOTS of strings, by using single quotes and concanetating variables in (I can't spell today...sigh)

    PHP Code:
    $string 'this is a string with '.$foo.' in it';

    // is marginally faster than

    $string "this is a string with $foo in it"
    The reason is php has to search through the string to find the variable.
    Quote Originally Posted by voostind View Post

    It's better to use a comma instead of a dot, because it saves some overhead (no string concatenation).

    PHP Code:
    // Example:
    echo 'foo''bar';
    // translates to:
    echo 'foo';
    echo 
    'bar';

    // whereas:
    echo 'foo' 'bar'
    // translates to:
    echo 'foobar' 
    The first is cheaper, because PHP doesn't first have to create the new string 'foobar', but can instead send the two strings to output directly.
    Quote Originally Posted by Anguz View Post

    to echo big chunks of html with vars in the middle using single quotes, instead of double quotes (slower) or jumping in and out of php, even if using shorthand, I do it like this

    PHP Code:
    echo 
       Hello,<br /> 
       My name is '
    ,$name,' ',$lastname,' and am ',$age,' years old.<br /> 
       I live in '
    ,$city,', ',$country,' since I was born.<br /> 
       You can contact me at '
    ,$email,' or by phone at ',$phone,'<br /> 
       Regards,<br /> 
       '
    ,$name,' ',$lastname,'<br /> 
    '

    it's very shorthand and fast... it can be very comfortable to use in a simple php template system
    Quote Originally Posted by louism View Post

    Consider using str_replace instead of the preg_replace or ereg_replace functions. The only reason why you would use preg_replace or ereg_replace functions would be that you REALLY need to use regular expressions. Also, as of PHP 4.0.5, every parameter in str_replace() can be an array, so theres no excuse to use preg or ereg fucntions when replacing simpel strings anymore.

    A useful use of str_replace() :

    PHP Code:
    $string="The quick brown fox jumps over the lazy dog.";
    $patterns[0] = "quick";
    $patterns[1] = "brown";
    $patterns[2] = "fox";

    $replacements[0] = "slow";
    $replacements[1] = "black";
    $replacements[2] = "bear";

    $string=str_replace($patterns$replacements$string);

    //$string="The slow black bear jumps over the lazy dog." 
    Quote Originally Posted by DR_LaRRY_PEpPeR View Post

    ereg vs preg
    When it comes to the regular expression functions, ereg* and preg*, the preg functions are the clear choice. The preg functions are generally twice as fast as their ereg counterpart. They also support more advanced regular expression operations. I can't think of any reason why you would need to use the ereg functions.

    preg manual page and pattern syntax (long and confusing but pretty good).
    Quote Originally Posted by Falesh

    Here's a bit of code I use to change new lines into XHTML <p>'s and <br />'s.

    PHP Code:
    // the first bit is to make both "\r\n" and "\r" line endings into "\n"
    $string str_replace("\r\n""\n"$string);
    $string str_replace("\r""\n"$string);

    // this next bit first adds an opening <p> then makes all double line breaks into </p><p>
    $string "<p>".str_replace("\n\n""</p><p>"$string);

    // finally this turns any single line breaks into <br />'s and closes the last <p>
    $string str_replace("\n""<br />"$string)."</p>"
    Last edited by Mittineague; Aug 2, 2013 at 19:03.

  3. #3
    SitePoint Wizard
    Join Date
    Oct 2001
    Posts
    2,686
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    MySQL



    As of PHP version 5.5 the MySQL functions have been Deprecated and should no longer be used.
    all mysql_ functions
    http://php.net/manual/en/migration55.deprecated.php
    ext/mysql deprecation

    The original MySQL extension is now deprecated, and will generate E_DEPRECATED errors when connecting to a database. Instead, use the MySQLi or PDO_MySQL extensions.




    Quote Originally Posted by louism View Post

    Quick tips :
    Never forget to use mysql_escape_string() when storing data into a database, to avoid SQL injection attacks:

    PHP Code:
    $sql="SELECT * FROM table WHERE username='";
    $sql.=mysql_escape_string($username)."'"
    What are sql injection attacks ?
    Remember that a malicious user can change any input to anything (number, string, etc). Many sites have some type of user login (username password) and they check it against a database of usernames and passwords with a mysql query like this:

    PHP Code:
    "SELECT COUNT(*) FROM USERLIST WHERE USER='$user' AND PASS='$password'"
    If the result is 0, the login fails, if the result is 1, the login passes. What would happen if $user contained "admin';#"'. The query would now read

    PHP Code:
    "SELECT COUNT(*) FROM USERLIST WHERE USER='admin';# AND PASS='$password'"
    The semicolon denotes the end of a query, and the # means the rest of the line is a comment. Thus, it doesn't matter what password was entered, the query returns 1 row - access granted.

    Worse yet, what if user contained the string "';$query="DROP DATABASE db" (all data deleted) :

    PHP Code:
    $query="SELECT COUNT(*) FROM USERLIST WHERE USER='admin'"$query="DROP DATABASE db"
    The easy way to prevent this is to use the mysql_escape_string() function to prevent strings from breaking out of the query and doing damage.
    Ful explanation : http://www.sitepoint.com/article/794


    By: I87 (See orignal post)
    use the [function to backslash variables] on php.net

    http://php.net/manual/en/function.my...ape-string.php

    PHP Code:
    <?php 
    // Quote variable to make safe 
    function quote_smart($value

       
    // Stripslashes 
       
    if (get_magic_quotes_gpc()) { 
           
    $value stripslashes($value); 
       } 
       
    // Quote if not a number or a numeric string 
       
    if (!is_numeric($value)) { 
           
    $value "'" mysql_real_escape_string($value) . "'"
       } 
       return 
    $value


    // Connect 
    $link mysql_connect('mysql_host''mysql_user''mysql_password'
       OR die(
    mysql_error()); 

    // Make a safe query 
    $query sprintf("SELECT * FROM users WHERE user=%s AND password=%s"
               
    quote_smart($_POST['username']), 
               
    quote_smart($_POST['password'])); 

    mysql_query($query); 
    ?>
    Why?
    look here

    Quote Originally Posted by DR_LaRRY_PEpPeR View Post

    Quotes around numeric data in queries
    For numeric columns in MySQL, you shouldn't put quotes around any of their values in queries. As our resident database guru, MattR, says, "that is very non-standard and will only work on MySQL." But if it's unknown data, how do you know that it's numeric and not letters that will cause an error? You can make sure that only a number is used in the query by first type-casting the data as int (or float for decimal numbers):

    PHP Code:
    // If id is being passed in the URL 
    $id = (int) $_GET['id']; 

    $r mysql_query("SELECT * FROM table WHERE id=$id"); 
    Then even if id is set to "abc," the worst that can happen is a 0 will be used in the query. No quotes; no error.


    Column types and attributes
    1) Be familiar with MySQL's column types along with their ranges/lengths. You should use the smallest column type that will hold the data that you expect to store. Most of the time, you probably don't need INT, because MEDIUMINT, SMALLINT, or TINYINT have enough range. Using a smaller type saves space and speeds things up.

    2) Declare all of your columns NOT NULL unless you need to store NULL values (NULL is not the same as 0 or the empty string). If you need to store NULL, you'll know. Again, NOT NULL saves space and speeds things up.

    3) Making INT-family columns UNSIGNED will effectively double the positive range with the same storage requirement. For example, TINYINT's highest value is 127. TINYINT UNSIGNED's highest value is 255.


    Indexes and optimization
    1) First, I sometimes see people create tables like this:

    Code:
    CREATE TABLE table (
    	id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    	.....
    	KEY (id),
    	UNIQUE (id),
    	PRIMARY KEY (id)
    	)
    Do not make a column KEY, UNIQUE, and PRIMARY KEY. In this case, KEY and UNIQUE don't help anything. The PRIMARY KEY is a key and it is unique. By specifying 3 indexes, it wastes space and slows down write operations.

    2) Indexes/keys are the key (no pun intended) to fast queries (especially joins). The 3 types of indexes are PRIMARY, UNIQUE, and KEY/INDEX (same thing). It's hard to explain when and how to use indexes, so I'll just point you to some relevant pages in the MySQL manual: Speed of SELECT queries and How MySQL uses indexes.

    3) When you have your indexes setup, use EXPLAIN on SELECT queries to make sure your indexes are actually being used.

    Quote Originally Posted by voostind View Post

    MySQL column types

    It is not true that using the smallest column type possible leads to query results. The
    reason is that, internally, MySQL uses 32-bit integers for indexes. (At least, last time I
    checked it did.) So when you build an index on an integer-type like SMALLINT or TINYINT,
    it will still become a 32-bit integer in the accompanying index (possibly even resulting
    in worse performance when running queries!). There even was a time MySQL messed up indexes
    on integer columns that weren't 32-bit, but this probably isn't true anymore. (I don't use
    MySQL myself.) Of course it makes good sense to use smaller integer types that aren't
    indexed and have a limited range, like someone's age.

    Another reason for not using anything other than the default INT32 (INT == INT32) is that
    other software might not understand it. If, for example, you use an ODBC connection to a
    MySQL database, you should only use simple data types. Microsoft Access in particular,
    which is used a lot for these kind of things, will freak out otherwise.

    Declaring columns NULL or NOT NULL has nothing to do with optimization! It has to
    do with the design of the database. If some table can have empty fields (as specified in
    the design), it should be NULL, and not 0 or the empty string. This way, when some field
    holds the value 0 (or the empty string), you'll know it's not an empty field. It's a field
    that has an empty value, which is something quite different.

    Indexes and optimizations

    Of course you shouldn't define a single field as KEY, UNIQUE and PRIMARY KEY at the same
    time. But frankly I'm surprised that MySQL doesn't optimize this away. As soon as some
    field is already a PRIMARY KEY, it needn't create two additional indexes. Are you sure
    MySQL doesn't notice this? (If so, it's even more stupid than I thought...)

    Quote Originally Posted by redemption View Post

    as for declaring fields NOT NULL when you know the field is never gonna be NULL, i think you missed Doctor_Larry_Pepper's point...
    posted by the doc
    Declare all of your columns NOT NULL unless you need to store NULL values (NULL is not the same as 0 or the empty string). If you need to store NULL, you'll know.
    declaring a column NOT NULL saves 1 byte (or 1 bit, i forget... set me right on this)... that optimizes use of the memory used to store the fields... it makes a difference when you've a thousand record table

    Quote Originally Posted by voostind View Post
    as for declaring fields NOT NULL when you know the field is never gonna be NULL, i think
    you missed Doctor_Larry_Pepper's point...
    Yep. I competely overlooked. Sorry!

    declaring a column NOT NULL saves 1 byte (or 1 bit, i forget... set me right on this)...
    that optimizes use of the memory used to store the fields... it makes a difference when
    you've a thousand record table
    LOL! Even when it's one byte, it wouldn't matter! Thousands times 1 byte is 1,000 bytes is
    (officially) not even 1 kB! On one million records it would save less than 1 MB. Who
    cares? Only in really, really large databases it matters, but then storage is not likely
    to be much of a problem...

    Quote Originally Posted by redemption View Post
    Originally posted by voostind

    LOL! Even when it's one byte, it wouldn't matter! Thousands times 1 byte is 1,000 bytes is
    (officially) not even 1 kB! On one million records it would save less than 1 MB. Who
    cares? Only in really, really large databases it matters, but then storage is not likely
    to be much of a problem...
    yeah but programmers usually like to optimize everything... the doc is one of them and so am i (most times... when i'm not lazy)... and well actually it saves 1 byte or 1 bit (??) for each field... there're bound to be plenty of records and thus almost exponentially more fields...

    there's a better explanation for this NOT NULL thing... i read it somewhere but i forget... oh well, let the doc defend himself when he comes back

    Quote Originally Posted by DR_LaRRY_PEpPeR View Post

    most of the time you don't need to store NULL values in MySQL. 0 or the empty string works fine. for example, with an email column, if someone doesn't enter an email address, just store the empty string. i can't see any need for NULL.

    one column i do have NULL is an age column. if an age isn't entered, i store NULL, rather than 0. that way, in case i want to do something like SELECT AVG(age) FROM ..., only the people who have an age will be averaged because the grouping functions (except COUNT(*)) ignore NULL rows. if i had instead stored 0's, those rows would lower the average.

    don't use NOT NULL *IF* you need to tell the difference between an empty value (0 or empty string) and no value (NULL).

    Originally posted by voostind
    MySQL column types

    It is not true that using the smallest column type possible leads to query results. The
    reason is that, internally, MySQL uses 32-bit integers for indexes. (At least, last time I
    checked it did.) So when you build an index on an integer-type like SMALLINT or TINYINT,
    it will still become a 32-bit integer in the accompanying index (possibly even resulting
    in worse performance when running queries!). There even was a time MySQL messed up indexes
    on integer columns that weren't 32-bit, but this probably isn't true anymore. (I don't use
    MySQL myself.) Of course it makes good sense to use smaller integer types that aren't
    indexed and have a limited range, like someone's age.

    <snip>

    Declaring columns NULL or NOT NULL has nothing to do with optimization! It has to
    do with the design of the database. If some table can have empty fields (as specified in
    the design), it should be NULL, and not 0 or the empty string. This way, when some field
    holds the value 0 (or the empty string), you'll know it's not an empty field. It's a field
    that has an empty value, which is something quite different.
    i got my information from the MySQL manual. from Get your data as small as possible:

    One of the most basic optimisation is to get your data (and indexes) to take as little space on the disk (and in memory) as possible. This can give huge improvements because disk reads are faster and normally less main memory will be used. Indexing also takes less resources if done on smaller columns.
    Use the most efficient (smallest) types possible. MySQL has many specialised types that save disk space and memory.
    Use the smaller integer types if possible to get smaller tables. For example, MEDIUMINT is often better than INT.
    Declare columns to be NOT NULL if possible. It makes everything faster and you save one bit per column. Note that if you really need NULL in your application you should definitely use it. Just avoid having it on all columns by default.
    only the index pointers (is that what they're called?) are 32-bit. i just checked and changing a SMALLINT column to INT on an 880 row table increased the size of the index file. so obviously SMALLINT takes up less space in the index.

    it's even more important to use smaller types, when possible, on indexed columns. they can be compared faster when doing joins and other searches. and by being smaller, they not only save disk space, but require less disk reads/writes and allow more of the index to be kept in the key_buffer (if it's a large table and assuming the table stays in the table_cache, otherwise its index blocks are released from the key_buffer). the more things you can keep in memory, the less disk access you have. but you know that.

    declaring columns NOT NULL does have something to to with optimization. i'm not sure what the manual means by "you save one bit per column." i just checked on the 880 row table. removing NOT NULL (from one column) made the data file 840 bytes larger. so that looks more like 1 byte per row. of course the savings are multiplied for each column you make NOT NULL.

    when columns are NOT NULL, that's one less value to check for. some examples of where NOT NULL helps:

    Code:
    mysql> EXPLAIN SELECT * FROM table WHERE not_null_col IS NULL;
    +-----------------------------------------------------+
    | Comment                                             |
    +-----------------------------------------------------+
    | Impossible WHERE noticed after reading const tables |
    +-----------------------------------------------------+

    MySQL doesn't need to check the table because not_null_col can't possibly contain a NULL row.

    also, MySQL can do optimizations on things like ... LEFT JOIN t2 ON t1.col=t2.col WHERE t2.col IS NULL. in the manual, for EXPLAIN, it says this for a value in the Extra column:

    Extra
    ...
    Not exists
    MySQL was able to do a LEFT JOIN optimisation on the query and will not examine more rows in this table for the previous row combination after it finds one row that matches the LEFT JOIN criteria. Here is an example for this:

    SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;

    Assume that t2.id is defined with NOT NULL. In this case MySQL will scan t1 and look up the rows in t2 through t1.id. If MySQL finds a matching row in t2, it knows that t2.id can never be NULL, and will not scan through the rest of the rows in t2 that has the same id. In other words, for each row in t1, MySQL only needs to do a single lookup in t2, independent of how many matching rows there are in t2.
    Another reason for not using anything other than the default INT32 (INT == INT32) is that
    other software might not understand it. If, for example, you use an ODBC connection to a
    MySQL database, you should only use simple data types. Microsoft Access in particular,
    which is used a lot for these kind of things, will freak out otherwise.
    i'm aware of that. i don't know if it's an issue for most people, though. if it is, they'll probably know.

    Of course you shouldn't define a single field as KEY, UNIQUE and PRIMARY KEY at the same
    time. But frankly I'm surprised that MySQL doesn't optimize this away. As soon as some
    field is already a PRIMARY KEY, it needn't create two additional indexes. Are you sure
    MySQL doesn't notice this? (If so, it's even more stupid than I thought...)
    it seems to be pretty stupid. when you do a SHOW INDEX FROM table, it shows 3 indexes. i too thought it might ignore the KEY and UNIQUE.

    Quote Originally Posted by Egghead View Post

    Databases and Tables
    When putting SQL queries into your PHP scripts, you should create a seperate file which sets the names of each database or table. This file can then be included when required, and if any database or table name needs to be changed, then you only need to make one alteration - not many! This is very useful when you are using scripts from other people which create databases/tables, as their script may create a new database/table with the same name as one you already have.
    Example configuration file:

    PHP Code:
    // Database Table Names 
    $conf['tbl']['books'] = 'book_names'
    $conf['tbl']['authors'] = 'writers'

    Any query can then use the defined names as so:
    PHP Code:
    $table "$conf['tbl']['books']"
    $field 'field_value' 
    $sql   'UPDATE ' $table 
             
    'SET my_field = ' $field 
             
    '\''
             
    // Note: a backslash is missing here!' 

    $table "$conf['tbl']['authors']"
    $field 'field_value' 
    $sql   'UPDATE ' $table 
             
    'SET my_field = ' $field 
             
    '\''
             
    // Note: a backslash is missing here! 
    NOTE: The VB Code in this forum keeps removing a backslash from the PHP source code.
    All lines reading
    ' ' ' ;
    should in fact read
    ' \ ' ' ;

    Quote Originally Posted by Dr Livingston View Post

    New to Database Design and Anaylsis ? Unsure on what Database Normalisation means ?

    Umm... Learn the basic 3 forms of database normalisation by reading this PDF file from OReilly; Fair enough it's Java though Database Design and Analysis is platform neutrol folks...

    http://www.oreilly.com/catalog/javad...apter/ch02.pdf

    Quote Originally Posted by Kilroy View Post

    this:
    Code:
    SELECT author, title, description FROM content
    is more preferred than

    Code:

    Code:
    SELECT * FROM content
    even when you are selecting everything anyway. This is because if you don't, your RDBMS will have to look for the columns first, and then select the content from then, but now, it just selects the content right away, which is slightly faster .

    Quote Originally Posted by Icheb View Post

    If you SELECT * and expand your table later, you also query rows you don't need.

    Quote Originally Posted by samsm View Post

    I'm not convinced that using the * wildcard is an altogether bad thing. Certainly, it has its limitations, but it does what it does and it is standard SQL.

    You use it when you want to select every column in a table. It works perfectly for that. If you just want to select specific columns, list those specific columns. No big deal.

    Quote Originally Posted by fine View Post

    batch insert text into mysql by using phpmyadmin

    If you have formated text files,(tab delimited, or csv), it is convenient to use phpmyadmin to do batch insert.

    Quote Originally Posted by Mytch2001 View Post

    I think that one useful PHP/MySQL tip that has helped me is MySQL's RAND() function, to get a random row:

    Code:
    SELECT * FROM myTable WHERE age > 20 ORDER BY RAND() LIMIT1
    Gets one random row from myTable where the age is greater than 20.
    Last edited by Mittineague; Aug 2, 2013 at 19:06. Reason: delinking broken links

  4. #4
    SitePoint Wizard
    Join Date
    Oct 2001
    Posts
    2,686
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    GLOBALS



    http://php.net/manual/en/security.globals.php
    Using Register Globals
    Warning

    This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.




    Quote Originally Posted by DR_LaRRY_PEpPeR View Post

    First and foremost, I believe, is the use of register_globals. For those of you who don't know, register_globals allows you to access variables from forms and URLs (such as file.php?var=foo) as $var in your script -- "magically" created global variables. Unfortunately, this old method continues to be used in most tutorials/examples. The PHP developers seem to have realized that register_globals was a bad idea, though. They discuss Using Register Globals in the PHP manual and recommend turning them off in php.ini:

    :Note that register_globals is going to be deprecated (i.e., turned off by default) in the next version of PHP, because it often leads to security bugs.
    ...
    You should do your best to write your scripts so that they do not require register_globals to be on
    In fact, as of PHP 4.2.0, register_globals is now off by default on new PHP installations. By writing code that relies on register_globals being on, you risk having that code not work on some systems! Wouldn't you rather use the preferred method of accessing variables and have your code work on all PHP installations?

    The proper way to access these variables is via their respective arrays. So instead of $var, in the above example, you should use $_GET['var']. Similarly, use $_SERVER['HTTP_USER_AGENT'] instead of just $HTTP_USER_AGENT.

    The main arrays are $_GET, $_POST, $_COOKIE, and $_SERVER, depending on where the variable came from, obviously. You can read more about them, and a couple of others, here and here in the manual.

    Please access your variables via these arrays!

    security
    about the security stuff. when register_globals is off, it doesn't matter how many variables a hacker tries to add in the URL/form/cookie, they will stay in the $_* arrays doing no harm unless you access them. when register_globals is on or you extract() the arrays, any variable that is supplied will be in your script, even though you never expected it to be. however, as i said, when they're in the arrays, they'll never affect anything! it's OK to do

    $id = $_GET['id']

    and i do all the time, because YOU are creating the $id variable, and you know it's from the URL since it's in the $_GET array. again though, if register_globals is on or the arrays are extract()ed, and you never used $id in your script, it would be created if `id=' was put in the URL. that's exactly what i don't want.

    i hate that these global variables were ever created. it's just wrong IMO to not know where user variables came from. they should be confined to something like an array to keep them harmless; and they are when register_globals is off and you access them via these arrays -- the way, and only way, it should've been all along.

    Quote Originally Posted by scoates View Post

    That said, it IS possible to maintain security while using register globals.

    I have a template (init_admin) that is called before the regular init template. It sets up some admin data.

    init checks to see if $ADMIN_INIT is true, if so, carries out some admin-related code.

    To make sure $ADMIN_INIT was set by me, and not by my client, I do something like this:

    PHP Code:
    if ($ADMIN_INIT and 
        !isset(
    $_GET['ADMIN_INIT'] and 
        !isset(
    $_POST['ADMIN_INIT'] and 
        !isset(
    $_COOKIE['ADMIN_INIT'] and 
        !isset(
    $_SESSION['ADMIN_INIT']) 
        { 
        
    // do admin stuff 
    } else { 
        die (
    "ADMIN_INIT tampering"); 

    it's more work, but it lets me keep register_globals on (unfortunately, I need register-globals, because IIS doesn't allow a per-site php.ini like apache).

    Quote Originally Posted by GeekSupport View Post

    useful link redux pointed out to me

    http://www.sitepointforums.com/showt...ight=.htaccess

    shows how to override php.ini settings and a snippet to save legacy code with minimal modification when upgrading to register_globals=off

    Quote Originally Posted by weirdbeardmt View Post

    You can use: "PHP_FLAG register_globals OFF" in an .htaccess to turn register_globals off.

    Quote Originally Posted by Egghead View Post

    Register Globals is now turned off by default, and most coders are getting used to implementing $_POST['variable'] and so on into their scripts. Note for Windows users: If your php.ini file still sets "register_globals = On" because you kept your php.ini settings on an upgrade then it may be a good idea to change it - even if it is just on your home or local machine for your own personal use (It is good practice to get into secure habits).

    What if you can not change the setting though? You may be using an ISP/host which sets "register_globals = On" for compatibility reasons and refuse to change it. Well shame on your ISP, however there are things you can do about it! First you may want to check the status of the register_globals setting, simply issue the phpinfo() function on the server and check the register_globals value in the PHP Core table.

    If it is "On" and you can not change it to "Off" by editing the setting, then you have a few options to make your code more secure.
    1. Put all your code into a function, then call the function. The scope of variables in functions will save the day for you.
    2. Manually use a function to unregister globals. If you first save the superglobals, you can then copy them back after the unregistering is done.

    PHP Code:
    function unregister_globals() 

       
    // Save the existing superglobals first 
       
    $REQUEST $_REQUEST
       
    $GET $_GET
       
    $POST $_POST
       
    $COOKIE $_COOKIE
       if (isset(
    $_SESSION)) 
       { 
          
    $SESSION $_SESSION
       } 
       
    $FILES $_FILES
       
    $ENV $_ENV
       
    $SERVER $_SERVER

       
    // Unset the $GLOBALS array (clear all) 
       
    foreach($GLOBALS as $key => $value
       { 
          if (
    $key != 'GLOBALS'
          { 
             unset(
    $GLOBALS[$key]); 
          } 
       } 

       
    // Re-assign the saved superglobals again 
       
    $_REQUEST $REQUEST
       
    $_GET $GET
       
    $_POST $POST
       
    $_COOKIE $COOKIE
       if (isset(
    $SESSION)) 
       { 
          
    $_SESSION $SESSION
       } 
       
    $_FILES $FILES
       
    $_ENV $ENV
       
    $_SERVER $SERVER

    unregister_globals(); 
    Apologies to Theo Spears of php|architect magazine (http://www.phparch.com). You can read his two other methods for solving the register globals problem and also other ideas for "Writing Secure PHP Code" in the January 2003, Volume II, Issue 1 edition of the magazine, which is available FREE.

    Quote Originally Posted by McGruff View Post

    Security with register_globals
    I'm not sure if it's good to recommend E_ALL & E_NOTICE though - although I note you only say this is a minimum.

    & E_NOTICE doesn't catch undefined variable/index errors, which can be a big security risk with reg globs on (in a shared environment you might be stuck with that).

    If a hacker has bombarded your script with a bunch of vars which are declared with reg globs there are three options.

    One: these variables aren't native to your script. They sit around doing nothing.

    Two: the hacker has guessed some valid var names and his hacked vars are declared right at the start of the script. A few lines down, the script declares your own values for the vars, overwriting the hacked values. Once again, they do nothing.

    Three: you have undefined vars/indexes. You're porked.

    Always E_ALL for development..

    Quote Originally Posted by jaspalmxtech View Post

    If you're on a shared environment, and have no way of disabling register_globals, this little "unregister_globals" snippet could come in handy:

    PHP Code:
    <?php
    if (@ini_get('register_globals'))
    foreach (
    $_REQUEST as $key => $value)
    unset(
    $GLOBALS[$key]);
    ?>

    Quote Originally Posted by Durinthiam View Post

    Now that register_globals is by default, off. The key to using ?p=blah designs is by inserting into the top of your webpage

    PHP Code:
    $blah=$_GET["blah"]; 
    If the variable is from a link

    PHP Code:
    $blah=$_POST["blah"]; 
    If the variable is from a form

    PHP Code:
    $blah=$_SERVER["blah"]; 
    If the variable is from a server environment

    Quote Originally Posted by HarryF View Post

    Globals appear to make your life alot easier. But do not succumb to them!

    The downside of globals is they make code extremely hard to read and understand, particularily with large scripts or where you're including files or using classes. One day you're going to declare the wrong variable as global, and be condemned to purgatory, destined to spend the rest of your days debugging the same piece of code.

    In general, it's a good habit to start early, and only use globabls for things like a select few enviroment variables (such as $PHP_SELF and $_SERVER), if you're going to use them at all.

    Of course the real PHP Monks say:

    NEVER USE GLOBALS!

    Remember, globals, like magic_quotes ARE EVIL!

    Quote Originally Posted by Kymira View Post

    With regard to the whole "global vars are evil arguement," I would agree to a certain point.

    For things such as "$is_logged_in," then yes, I agree that global vars are evil. On the other hand, if you look at phpBB's code, the use global vars for internal variables such as "global $db." In this case, $db is a database abstraction layer that that entire project uses. For example:

    PHP Code:
    /* simply authenticating users with plain text is bad in my opinion, but this is just an example*/ 
    function auth_user(&$username, &$password

       global 
    $db

       
    $query "SELECT blah, blah....."

       
    $result $db->sql_query($query); 

       
    $auth_array $db->sql_fetchrow($result); 

       
    /* more code to process the results, but not important to this example */ 

    For something like this, the $db class is used throughout the script, and it's easier than having to constantly pass the $db class to a function. Apparently there are problems with passing objects to a function, and using global vars in this way can help augment that.

    Quote Originally Posted by voostind View Post

    For things such as "$is_logged_in," then yes, I agree that global vars are evil. On the other hand, if you look at phpBB's code, the use global vars for internal variables such as "global $db." In this case, $db is a database abstraction layer that that entire project uses.
    So you're saying in some cases it's okay to use globals. Well, it's not (IMHO). The fact that a program uses globals can never be rectified by the reason for using them, as far as I'm concerned. So in this case I'd say: phpBB has a design problem, because it has to have at least one global variable to work properly...


    Post by voostind about globals
    Last edited by Mittineague; Jul 31, 2013 at 22:11.

  5. #5
    SitePoint Wizard
    Join Date
    Oct 2001
    Posts
    2,686
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Misc.



    As of PHP version 5.5 the MySQL functions have been Deprecated and should no longer be used.
    all mysql_ functions
    http://php.net/manual/en/migration55.deprecated.php
    ext/mysql deprecation

    The original MySQL extension is now deprecated, and will generate E_DEPRECATED errors when connecting to a database. Instead, use the MySQLi or PDO_MySQL extensions.




    Quote Originally Posted by DR_LaRRY_PEpPeR View Post
    PHP tags
    I recommend always using the full PHP open tag, <?php, rather than the short one, <?. This means also that instead of <?=$var?>, it's better to use the full <?php echo $var?>. Using the full open tag ensures that your code will work on all PHP installations, regardless of the short_open_tag setting.


    Alternative control structure syntax
    I highly recommend staying away from the if (): ... endif; style syntax and sticking with curly braces, if () { ... }. This is the preferred syntax and it makes your code easier to read.


    error_reporting
    You should probably test your code with error_reporting set to at least E_ALL & ~E_NOTICE (all errors except notices) so that you aren't suppressing errors that should be fixed. error_reporting can be set in php.ini or with the error_reporting() function.

    Quote Originally Posted by HarryF View Post

    User defined functions
    User defined functions allow you to re-use chunks of your code. Say for example you have an script where you are FTPing a files in a few places. You might declared a function like;

    PHP Code:
    function ftpcopy ($ftpserver,$ftppath,$ftpuser,$ftppassword,$filename) { 
        
    $fp 0;     
        
    $fp ftp_connect($ftpserver); 
        
    $login ftp_login ($fp$ftpuser$ftppassword); 
        
    ftp_chdir($fp$ftppath); 
        
    ftp_put($fp$filename$filenameFTP_BINARY);   
        
    ftp_quit($fp); 

    You then call this function elsewhere in your code, passing it the variable is needs, e.g.

    PHP Code:
    ftpcopy ("ftp.yourdomain.com","/pub/","anonymous","php@yourdomain.com","myfile.tar.gz"); 

    Quote Originally Posted by kamstar View Post

    my tiny bit of advice...its probably a good idea to add comments to your code (as seen above);

    PHP Code:
    //single line comment 

    # another single line comment 

    /* multi line comment 
       multi line comment */ 
    http://www.php.net/manual/ro/languag...x.comments.php

    Quote Originally Posted by z00om View Post

    In some cases, people are programming across different platforms, or using various editors. This is a definate hazard! Because different operating systems use different newlines, different spaces sometimes, and things can get really ugly when a file you wrote in windows is saved in unix then you try to edit it! So, I always keep these two practices in mind!

    At the end of every line, add a space. So if you lose all your new lines, most of your code is likely to be in tact and repairable... for example:

    PHP Code:
    <?php 
    if ($action == "whatever") { 
    echo 
    "You told us to do whatever!"

    ?>
    now say you lost all those new lines..

    PHP Code:
    <?php 
    if ($action == "whatever") { echo "You told us to do whatever!"; } ?>
    the code still functions 'cause you put the spaces in! And it's readable. This one goes along with my next one,

    I NEVER USE single line comments. I always use "multi-line" comments, because...

    if you type something like above, and you lose all your new lines again, your comments causes trouble because now everything is ONE LINE, and that ONE LINE is commented out! see:

    PHP Code:
    <?php // whatever check if ($action == "whatever") { echo "You told us to do whatever!"; } ?>
    oops! but, had you used this so-called "multi-line" comment, it'd be okay...

    PHP Code:
    <?php /* whatever check */ if ($action == "whatever") { echo "You told us to do whatever!"; } ?>
    (or atleast I think so?)

    And I know adding spaces adds bytes, but I'm willing to take on those extra bytes if it saves me 3 hours of recovering from new line problems!
    and think: a 1000 line script only takes on about .99 KB... thats not much and usually a script is 100-300 lines, thats only 0.3k!

    Quote Originally Posted by scoates View Post

    PHP doesn't interpret mac line endings.

    Sorry, I take it back.
    PHP on unix (Linux specifically) doesn't interpret \r as a line ending. PHP on Win32 DOES.

    \r line endings are probably gone with OSX anyway (I certainly HOPE so).

    \n or \r\n are both interpreted as line endings.
    Spaces are moot, as was mentioned.

    Quote Originally Posted by Jujubee View Post

    Here are 21 PHP tips from Zend.com that maybe should be linked from the first post in this thread:

    http://www.zend.com/zend/art/mistake.php
    http://www.zend.com/zend/art/mistake1.php
    http://www.zend.com/zend/art/mistake2.php

    Quote Originally Posted by HarryF View Post

    Use sessions for users currently actively browsing your website. Sessions are there to store data that's required for the users current visit. For example storing their username / password for your sites authentication system.

    Use cookies for long term data which you want to survice between visits by an individual users. For example you store their name in a cookie so that next time they come to your site, you can display "Welcome back HarryF!". The cookies would then "hand off" their data to the sessions for the current visit.

    Quote Originally Posted by HarryF View Post

    PHP: Hackers Paradise Revisited
    Stumbled upon this article today, from April 4th, 2001 (but it's still very applicable to the latest versions).

    Full of healthy goodness

    Quote Originally Posted by auroraeosrose View Post

    one thing I almost forgot - everyone who writes php should read this - yeah I know, those of you who have been coding php forever are so sick of the document, but it's a great piece for beginning coders who often don't think about security

    http://www.securereality.com.au/studyinscarlet.txt

    Quote Originally Posted by Kymira View Post

    When using a for loop, it's faster to set the end condition outside of the loop. Ex:

    PHP Code:
    $array_count count($_POST);

    for (
    $i '0'$i $array_count$i++)
    {
      
    $key array_search('on'$_POST);
      echo 
    $_POST[$key] . ' is on!';

    Why is this faster? Unlike C/C++, Java (etc), PHP is an interpretted language and isn't compiled down to machine language. So if you call a function inside a loop declaration, PHP will call that function every time it iterates though the loop.

    Quote Originally Posted by JoeRags View Post

    Regular expressions are one area that I think commenting is useful. Unfortunately it seems like some kind of trend to comment like above while leaving the following code without comments.

    For example, instead of:

    PHP Code:
    $expression '^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]{2,})+$'
    Try:

    PHP Code:
    $expression '^' 
    // One or more underscore, alphanumeric, or hyphen characters. 
    $expression .= '[_a-z0-9-]+'
    // Followed by zero or more sets consisting of a period and one or more 
    // underscore, alphanumeric, or hyphen characters. 
    $expression .= '(\.[_a-z0-9-]+)*'
    // Followed by an 'at' character. 
    $expression .= '@'
    // Followed by one or more alphanumeric or hyphen characters. 
    $expression .= '[a-z0-9-]+'
    // Followed by one or more sets consisting of a period and two or more 
    // alphanumeric or hyphen characters. 
    $expression .= '(\.[a-z0-9-]{2,})+'
    $expression .= '$'

    Quote Originally Posted by louism View Post

    Also, a lot of begginers wonder how to have VARIABLE variable names (variable who's naming depends on another variable).
    This is achieved by doing the following :

    PHP Code:
    $var_name="louis";
    $
    $var_name="Variable content.";

    //This will set $louis="Variable content."

    $var_name="supervar";
    $
    $var_name="Variable content.";

    This will set $supervar="Variable content." 
    You can also have variable function names :

    PHP Code:
    $funct_name="louis";
    function 
    $funct_name {
    //...
    }

    //This is the same as :

    function louis {
    //...


    SESSIONS
    A lot of beginners complain that their session variables don't get passed from page to page.
    Always use session_start(); at the beginning of each page to be able to retrieve session vars from the superglobal array $_SESSION

    HEADERS
    Consider the following:

    PHP Code:
     <?php
    header
    ("Location: index.html");
    ?>
    This will output a warning: headers already sent.
    Where's the mistake ?
    Look closer.
    Closer!
    It's the little blank space before the <?php tag ! Always send headers at the VERY beginning of the page.

    Quote Originally Posted by noddy View Post

    This is my favorite few lines of debug code. Allows humans to easily read the contents of an array.

    PHP Code:
    // debug - prints a nice formatted array, only need to pass it the name of the array 
    function print_format_array($array_name) { 
      echo 
    '<pre>'
      
    ksort($array_name); 
      
    print_r($array_name); 
      echo 
    '</pre>'
    // end func 

    Quote Originally Posted by Forbes View Post

    I have a tip for in-bound variables within classes.

    This method copies a bunch of stock super global variables into just one associative array variable:

    PHP Code:
    function getGlobals () { 

            
    // if any POST values are issued, they are dealt with here... 
            
    if (!empty($_POST)) { 

                
    $this->arrayActions Index::ValidateUserSessionTime($_POST); 

            
    // ... else, if any GET values are issued... 
            
    } elseif (!empty($_GET)) { 

                
    $this->arrayActions Index::ValidateUserSessionTime($_GET); 

            
    // ... else, if any COOKIE values are issued... 
            
    } elseif (!empty($_COOKIE)) { 

                
    $this->arrayActions Index::ValidateUserSessionTime($_COOKIE); 

            } 
    // end if 

        
    // end function getGlobals 
    And just to add some extra funk, each time a new variable enters the application, a call is made to a method which checks to see if this session is still active. If not, you're logged out:

    PHP Code:
    function ValidateUserSessionTime ($arrayActions) { 

            
    /** 

                When the User logs in, the session is assigned a UNIX date & time stamp. This stamp needs to be varified. 
                If the stamp is equal to or older than one hour, then the user is automatically logged out of whatever 
                application they happen to be at the time. 

            */ 


            // if the User is already logged in... 
            
    if (!empty($_SESSION['activetime'])) { 

                
    // if the User has been active for one hour or less... 
                
    if (($integerUNIXDateTImeStamp mktime(date("H"), date("i"), date("s"), date("m"), date("d"), date("Y")) - $_SESSION['activetime']) < SESSION_TIMEOUT) { 

                    
    // renew the account active date & time session 
                    
    $_SESSION['activetime'] = mktime(date("H"), date("i"), date("s"), date("m"), date("d"), date("Y")); 

                    
    // return an array of the global data 
                    
    return $arrayActions

                
    // ... else, log them out... 
                
    } else { 

                    
    // create the variables to automatically log the User out 
                    
    $arrayActions['action'] = "logout"

                    return 
    $arrayActions

                } 
    // end if 

            // ... else, if the User has only just entered... 
            
    } else { 

                
    // return an array of the global data 
                
    return $arrayActions

            } 
    // end if 

        
    // end function ValidateUserSessionTime 
    I've no doubt that there's room for improvement, or it maybe that others have done better.

    Quote Originally Posted by holmescreek View Post

    A simple tutorial on using PHP to load html page templates, for beginners to understand how to seperate code from html.

    http://www.sitepoint.com/forums/showthread.php?t=338850

    Quote Originally Posted by Jim Mautalent View Post

    A simple snippet for adding random numbers to a file while uploading to prevent files over-writing

    PHP Code:
    //The name of the file passed from the form 
    $file_name $_FILES['userfile']['name']; 

    //A random 6 digit number 
    $random_digit=rand(000000,999999); 

    //Put the random digit before the file name, using a decimal point to seperate the two variables 
    $new_file_name=$random_digit.$file_name

    //Sets the path (relative to the directory of your php script 
    //For instance, if you had public_html/quotescript/ and want the quotes in public_html/quotes/ then you would make $path ../quotes/ going back a step 
    //this example is if you want public_html/quotescript/quotes/ 
    $path"quotes/".$new_file_name

    //if there is a file 
    if($userfile !=none
    //open if statement 

    //Copy it to the path 
    if(copy($_FILES['userfile']['tmp_name'], $path)) 

    {
    //open if statement 
    echo $new_file_name

    //close if statement 
    else 
    //open else statement 
    echo "Error"
    // close else statement 
    // close if statement 
    NOTE: This is a very basic way of doing things with no deep error checking involved

    Quote Originally Posted by the DtTvB View Post

    Making Function Names Shorter:
    You can specify a variable with function name and do like this:

    PHP Code:
    $fetch 'mysql_fetch_assoc';
    $arr $fetch($result); // Will do the same as mysql_fetch_assoc 
    >>>> Falesh's comment: Might this be confusing to a different programmer? <<<<

    Making Variable Names Shorter:

    PHP Code:
    $some_really_long_variable 'some value';
    $s 'some_really_long_variable';
    echo $
    $s;
    // Notice 2 dollar signs! -- Outputs some value 
    Evaluate Variable Name:

    PHP Code:
    $y 'hello';
    ${
    'data_' $y} = 'test';
    // $data_hello has been set to 'test'
    echo $data_hello ' ' . ${'data_' $y};
    // Outputs test test 
    Many people may use this:

    PHP Code:
    $sql "SELECT * FROM table";
    $result mysql_query($sql);
    if (!
    $result)
        die (
    "<b>SQL: </b> $sql<br /><b>Error: </b>" mysql_error()); 
    Shorter Version:

    PHP Code:
    if (!$result mysql_query($sql "SELECT * FROM table"))
        die (
    "<b>SQL: </b> $sql<br /><b>Error: </b>" mysql_error()); 
    A really short if, then, else (yeah, you can't use echo here!)

    PHP Code:
    $z 5
    $z == ? print '$z is 5' : print '$z is not 5'
    A really short if, then (you can't use echo here too, so use print!)

    PHP Code:
    $z 5
    $z == && print '$z is 5'
    This technique is useful when writing this code:

    PHP Code:
    get_error() && die('An error has occured!'); 
    // Error and die! 
    A really short if not, then (you can't use echo here too, so use print!)

    PHP Code:
    $z 4
    $z == || print '$z is not 5'
    This technique is useful when writing this code:

    PHP Code:
    check_secess() || die('An error has occured!'); 
    // Sucess or die! 

    Quote Originally Posted by jahLives View Post

    In very big projects, I like simulating namepaces for a better API and code overview!

    Instead of:

    PHP Code:
    function getGbEntries() 

    ... 

    function 
    displayGbEntries($ary

    ... 


    $rows getGbEntries(); 
    displayGbEntries($rows); 
    Rather do:

    PHP Code:
    class GB 
      
    function getEntries() 
      { 
        .. 
      } 
      function 
    display($rows
      { 
        .. 
      } 

    $rows GB::getEntries(); 
    GB::display($rows); 
    PHP self does not allow using real namespaces, but with this method, you can simulate them. I like this technique very very much!

    Quote Originally Posted by Falesh View Post

    Try using a text editor that lets you navigate to functions.

    I found this when using Notepad++ (a free text editor). I had just put all my functions into a separate file and then found that if you select the Plugins menu, then Function List and click View List it brings up a box with a list of all the function names in the file. If you click on a function name it moves you to the start of that function.

    This has been a revelation to me for moving around my code and keeping my head around what functions I have.
    Last edited by Mittineague; Aug 2, 2013 at 19:08.

  6. #6
    SitePoint Evangelist AlienDev's Avatar
    Join Date
    Feb 2007
    Location
    UK
    Posts
    591
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)


    As of PHP version 5.5 the MySQL functions have been Deprecated and should no longer be used.
    all mysql_ functions
    http://php.net/manual/en/migration55.deprecated.php
    ext/mysql deprecation

    The original MySQL extension is now deprecated, and will generate E_DEPRECATED errors when connecting to a database. Instead, use the MySQLi or PDO_MySQL extensions.




    My tip (I noticed nobody ever wrote this in any articles anywhere which gave me lots of problems until I found it out my self):

    When using mysql_real_escape_string() or addslashes() it changes ' and " to \' and \" which we all know, right? But when adding the variables to the mysql database it doesnt actually put the backslashes into the table. You DONT need to use strip slashes when bringing data out of the table because the backslashes arent added!

    Probably sounds like I'm stupid, but there is not one article that I learned from which told me "the backslashes arent actually added to the database".
    Last edited by Mittineague; Aug 2, 2013 at 19:09.

  7. #7
    SitePoint Enthusiast
    Join Date
    Jun 2007
    Posts
    25
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, the name of the thread is "PHP and MySQL coding tips" but I see many people submitting code that can be useful. And now the debug class I'm using in conjunction with the above db class and the q() function:

    PHP Code:
    class debug
    {
        function 
    explain($var$echo true)
        {
            
    $out '<table border="1" cellspacing="0" cellpadding="3" style="text-align:left;margin:1em;">';
            
    $type gettype($var);

            switch (
    $type)
            {
                case 
    'boolean':
                    
    $var = ($var?'true':'false');
                case 
    'integer':
                case 
    'double':
                case 
    'NULL' :
                case 
    'string':
                    
    $out .= '<tr><th style="color:#a71">'.$type.' :</th><td>'.htmlspecialchars($var).'</td></tr>';
                    break;
                case 
    'array':
                    
    $out .= '
                        <tr>
                            <th colspan="2" style="color:#a71">ARRAY</th>
                        </tr>
                        <tr style="color:#196">
                            <th>KEY</th>
                            <th>VALUE</th>
                        </tr>'
    ;
                    foreach ( 
    $var as $key => $value )
                    {
                        
    $out .= '<tr><th>'.htmlspecialchars($key).'</th><td>'.nl2br(htmlspecialchars($value)).'</td></tr>';
                    }
                    break;
                case 
    'unknown type':
                    
    $out .= '<tr><th colspan="2" style="color:#a71">'.$type.' :</th></tr>';
                    break;
                case 
    'object':
                    
    $className get_class($var);
                    
    $vars get_class_vars($className);
                    
    $methods get_class_methods($className);
                    
    $out .= '
                    <tr>
                        <th colspan="2" style="color:#a71; text-align:center;">'
    .$type.'</th>
                    </tr>
                    <tr>
                        <th>instance of :</th>
                        <td>'
    .$className.'</td>
                    </tr>
                    <tr>
                        <th colspan="2" style="color:#966;">PROPERTIES :</th>
                    </tr>
                    <tr>
                        <td colspan="2">'
    .(empty($vars)?'none':debug::explain($vars,false)).'</td>
                    </tr>
                    <tr>
                        <th colspan="2" style="color:#36b;">METHODS :</th>
                    </tr>
                    <tr>
                        <td colspan="2">'
    .(empty($methods)?'none':debug::explain($methods,false)).'</td>
                    </tr>
                    '
    ;
                    break;
                case 
    'resource':
                    
    $out .= '
                    <tr>
                        <th colspan="2" style="color:#a71;text-align:center;">'
    .$type.'</th>
                    </tr>
                    <tr>
                        <th>'
    .get_resource_type($var).' :</th>
                        <td>'
    .$var.'</td>
                    </tr>'
    ;
                    break;
            }

            if ( 
    $type == 'string' && function_exists($var) )
                
    $out .= '<tr><th colspan="2" style="color:#36b">also a function name</th></tr>';

            if ( 
    $type == 'string' && class_exists($var) )
                
    $out .= '<tr><th colspan="2" style="color:#36b">also a class name</th></tr>';

            
    $out .= '</table>';

            if ( 
    $echo )
                echo 
    $out;

            return 
    $out;
        }

        function 
    dbgWriteDb($msg)
        {
            
    db::q'insert into debug values(null, %se)'$msg );
        }

        function 
    showMysqlError($where 'screen')
        {
            
    $err mysql_error();
            if ( 
    $where == 'db' )
                
    debug::dbgWriteDb('last mysql error : '.$err);
            else
                echo 
    $err;
        }

    The explain() function is a nice replacement for native functions like var_dump() etc. It can explain all type of variables in a better format. It returns the output and if $echo is true, which is the default value, it also prints to the screen.

    dbgWriteDb() -> This one obviously writes the input value to a table including two columns : an id and a message of type text.

    And the showMysqlError(). You will need the function mysql_error() frequently in case of errors. And there can be times that it is impossible to output the error to the screen. One example is a custom class that uses the database as the session storage instead of the default file system. Since some session job have to happen before any output sent, if there is a database error, you cannot see it on your screen. Instead, you can direct it to a database table. This function writes the error either to the screen (default) or to the database.

    Examples:

    PHP Code:
    debug::explain($_SERVER); 
    prints all $_SERVER variables to the screen in a nice format.

    PHP Code:
    debug::showMysqlError('db'); 
    records the last MySQL error to the database.
    Last edited by halil; Aug 19, 2007 at 13:12. Reason: Some more formatting and correction

  8. #8
    masquerading Nick's Avatar
    Join Date
    Jun 2003
    Location
    East Coast
    Posts
    2,215
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This might have been mentioned before, but I didn't see it. Anyways, it's a small performance increase trick - unnoticeable in 99&#37; of the cases, but could make a bit of difference in very large apps. echo actually takes parameters, unlike print, which means if you are using it to print out strings and variables, you don't have to concatenate, you can do it like this:

    PHP Code:
    echo "Hi, my name is "$name" and I live in "$town"."
    Which is actually just a tid bit faster than using .

    [construed from the php manual]
    Nick . all that we see or seem, is but a dream within a dream
    Show someone you care, send them a virtual flower.
    Good deals on men's watches

  9. #9
    SitePoint Zealot Anagram's Avatar
    Join Date
    Feb 2003
    Location
    Norway
    Posts
    109
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    if you have a simple statement with something that needs to happen if some criteria is set, you *could* do this:

    PHP Code:
    if ($a==1) {
    $b='blue';
    } else {
    $b='yellow';

    However, using ternary operators, you could shrink it down to this:

    PHP Code:
    $b $a=='blue' 'yellow'
    If pigs could fly, the prize of bacon would reach the sky.

    www.dosspirit.net - Norwegian
    reviews of DOS games

  10. #10
    SitePoint Guru risoknop's Avatar
    Join Date
    Feb 2008
    Location
    end($world)
    Posts
    834
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi guys. Here is a simple function I often use to format text from textarea into nice XHTML.

    What it basically does - it removes newlines and inserts HTML paragraph tags (<p>, </p>) and breaks (<br />).

    PHP Code:
    /*
    Function: nl2p
    Purpose: Format a plain text with newlines into an XHTML markup with paragraphs
    */
    function nl2p($string) {
      
    $string "<p>" $string "</p>";
      
    $string str_replace("\r\n\r\n""</p><p>"$string);
      
    $string str_replace("\r\n""<br />"$string);
      
    $string str_replace("</p><p>""</p>\n<p>"$string);
      
    $string str_replace("\r"''$string);
      
    $string str_replace("<p></p>"''$string);
      return 
    $string;

    You can also use reversed function to replace paragraphs and break tags with newlines:

    PHP Code:
    /*
    Function: p2nl
    Purpose: Format an XHTML markup with paragraphs into a plain text with newlines
    */
    function p2nl($string) {
      
    $string str_replace("</p>\n<p>""\r\n\r\n"$string);
      
    $string str_replace("<br />""\r\n"$string);
      
    $string strip_tags($string);
      return 
    $string;

    I hope some of you will find it useful
    Last edited by risoknop; Sep 10, 2008 at 04:44.

  11. #11
    SitePoint Guru risoknop's Avatar
    Join Date
    Feb 2008
    Location
    end($world)
    Posts
    834
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here's how to insert an UNIX timestamp into MySQL. I learned it yesterday:

    PHP Code:
    $date $time() // This produces an UNIX timestamp
    $sql "INSERT INTO table (column) VALUES (FROM_UNIXTIME($date))"// And this is a query you need to run 
    This is probably trivial to most of you but I was very surprised to find out about this approach. Until yesterday I have been keeping date and time information in database just as strings.

    In addition, here is how to select an UNIX timestamp from a database:

    PHP Code:
    $sql "SELECT UNIX_TIMESTAMP(column) FROM table WHERE ..."// You need to run this query 
    Last edited by risoknop; Sep 10, 2008 at 04:43.

  12. #12
    SitePoint Guru rageh's Avatar
    Join Date
    Apr 2006
    Location
    London, Formerly Somalia
    Posts
    612
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The most important tip any PHP beginner must have is: to turn the error reporting on when developing script. Putting this single line
    Code PHP:
    at the top of your code is a life-savier.

    When error reporting is not on, PHP masks many warnings that could potentially bring down your application, and when that happens, it is hard to find the problems which are often misspelt variables and variables that have not been set or not available in that part of the code.

    Equally impotant is that you take the error reporting off when you put your code in a live website.

    Hope that helps somebody.

    Rageh
    ------------------

  13. #13
    SitePoint Wizard spence_noodle's Avatar
    Join Date
    Jan 2004
    Location
    uk, Leeds (area)
    Posts
    1,264
    Mentioned
    2 Post(s)
    Tagged
    1 Thread(s)
    Email Attachment Coding Tip

    Just recently I've been trying to send an email with an attachment (an image file) using php. I know how to send an email with no attachment so this was new to me and after a few days work and looking at other scripts I've came up with the code below. I had a look at Phpmailer after so many attempts and failing. The script worked a treat but I did wondered how?

    After looking through the script it became clear that more than one random hash code was needed. This does not mean two different codes had to be randomly made but (as you will see below) before the codes different names can be used to split them both apart. In this case "b1_" and "b2_" are used.

    PHP Code:
    // Send an email with the fileattached
    $file_dir "images"// image directory
    $file_name "myimage.jpg"// file

    $file fopen($file_dir.'/'.$file_name,'rb');
    $data fread($file,filesize($file_dir.'/'.$file_name));
    fclose($file);
     
    $data chunk_split(base64_encode($data));
                     
    $email_from "from@website.com"// Who the email is from 
    $email_to "to@website.com"// Who the email is too
    $email_subject "Subject/Title Goes here"//The subject

    $random_hash md5(date('r'time())); 

    // Now build up the email starting with the headers
    $headers "From: from@website.com\r\nReply-To: to@website.com\r\n"
    $headers .= "MIME-Version: 1.0
    Content-Type: multipart/mixed;
        boundary=\"b1_
    {$random_hash}\"";

    $email_message "--b1_{$random_hash}
    Content-Type: multipart/alternative;
        boundary=\"b2_
    {$random_hash}\"

    --b2_
    {$random_hash}
    Content-Type: text/plain; charset = \"iso-8859-1\"
    Content-Transfer-Encoding: 8bit


    Email message goes here.

        
    "
    ;

    $email_message .= "--b2_{$random_hash}--
    --b1_
    {$random_hash}
    Content-Type: image/jpeg; name=\"
    {$file_name}\"
    Content-Transfer-Encoding: base64
    Content-Disposition: attachment; filename=\"
    {$file_name}\"

    {$data}--b1_{$random_hash}--";            
        
    mail($email_to$email_subject$email_message$headers); 
    The above code shows it starts with "b1_" first which is for the file attachment then the email message then ends "b1_" and starts "b2_" for the text part of the email. After the message ends "b2_" is ended then "b1_" is started again for the file attachment. Each code uses the same random code throughout.

    The content type can be changed to suit the file being attached.

    spence
    "Don't you just love it when you solve a programming bug only to create another."

  14. #14
    SitePoint Wizard spence_noodle's Avatar
    Join Date
    Jan 2004
    Location
    uk, Leeds (area)
    Posts
    1,264
    Mentioned
    2 Post(s)
    Tagged
    1 Thread(s)
    Email() & Hotmail

    If you are having trouble with sending email with mail() to hotmail, then please try the following:

    1. Log into your Cpanel and open your webmail (you will need an email account thats been created in the Cpanel), create and send an email to your hotmail account. If no email arrives (and it's fairly quick) then it's your hotmail account.
    2. Open your hotmail account through your web browser. Mine has the 'Options' tab on the right handside, click that to reveal the drop down menu. The last tab is another link called 'More Options', click this to open up another page.
    3. Under the heading 'Junk E-mail' click onto the link 'Filters and reporting', now choose 'Standard' (if it's not already chosen) under the junk e-mail filter heading.
    4. Now try again to send an email through your webmail account.

    If the above fails, try the lower setting in your junk e-mail filter, other than that it will tell you if your ip address for your website is blocked, it's at this point to contact the webhost.
    "Don't you just love it when you solve a programming bug only to create another."

  15. #15
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Single or Double quotes for strings?

    Here are the results of combing through the top ten search results for php code conventions, as they apply to quoting strings.

    1. Zend Framework - Coding Style
    When a string is literal (contains no variable substitutions), the apostrophe or "single quote" should always be used to demarcate the string

    2. PHP Coding Standard (dagblato.no)
    [no preference]

    3. Stack Overflow - Which coding conventions to follow for PHP
    For PHP, i'd suggest to follow Zends suggestions [as in #1]

    4. OrangeHRM PHP Coding Standards
    When a string is literal (contains no variable substitutions), the apostrophe or "single quote" should always be used to demarcate the string

    5. PEAR Coding Standards
    [no preference]

    6. PHP Chapter Conventions
    [unrelated]

    7. Drupal Coding Standards
    Drupal does not have a hard standard for the use of single quotes vs. double quotes. Where possible, keep consistency within each module, and respect the personal style of other developers.

    With that caveat in mind: single quote strings are known to be faster because the parser doesn't have to look for in-line variables. Their use is recommended except in two cases:
    • In-line variable usage, e.g. "<h2>$header</h2>".
    • Translated strings where one can avoid escaping single quotes by enclosing the string in double quotes. One such string would be "He's a good person." It would be 'He\'s a good person.' with single quotes. Such escaping may not be handled properly by .pot file generators for text translation, and it's also somewhat awkward to read.


    8. cartoweb .org Code Convention
    Coding Style - Developers should use the PEAR coding standards as the coding style reference in CartoWeb [which state] Things like "single quotes vs double quotes" are features of PHP itself to make programming easier and there are no reasons not use one way in preference to another. Such best practices are left solely on developer to decide.

    9. TuVinh PHP Coding Convention
    [no preference]

    10. evolt.org PHP coding guidelines
    Strings in PHP can either be quoted with single quotes ('') or double quotes (""). The difference between the two is that the parser will use variable-interpolation in double-quoted strings, but not with single-quoted strings. So if your string contains no variables, use single quotes and save the parser the trouble of attempting to interpolate the string for variables

    Summary
    Prefer single quotes: Zend, Stack Overflow, orangeHRM, Drupal, Evolt
    No preference: Dagblato, Pear, Cartoweb, TuVinh
    Prefer double quotes: none
    Last edited by paul_wilkins; Jun 9, 2011 at 20:29.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  16. #16
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Handling Input and Output

    Due to the demise of magic quotes, we need to change how we approach and handle global values from places such as $_GET and $_POST.
    Here's what we're going to be looking at:

    1. Getting the values
    2. Disabling magic quotes
    3. Handling values
    4. Protect the database
    5. Output to the page


    1. Getting the values

    You can use one of the two following sets of code to retrieve a value:

    Code php:
    // retrieve a value without filter_input
    $email = '';
    if (isset($_GET['email'])) {
        $email = $_GET['email'];
    }

    Code php:
    // filter_input can be used from PHP 5.2 onwards
    $email = filter_input(INPUT_GET, 'email');

    The benefit of using filter_input is that you can also apply filters to the values. For example, with an email address there is the FILTER_SANITIZE_EMAIL filter, which removes all characters except letters, digits and !#$%&'*+-/=?^_`{|}~@.[].

    Code php:
    $email = filter_input(INPUT_GET, 'email', FILTER_SANITIZE_EMAIL);

    2. Disabling magic quotes

    None of the above yet protects your code from potentially malicious input. Up to PHP 5.3 it's magic quotes that attempted to provide the protection, but they were flawed. The slashes that magic quotes added, are normally stripped out in favour of using mysql_real_escape_string or prepared statements, which provide better protection. As of PHP 5.3 the magic quotes are officially deprecated. In PHP 6.0 they won't exist at all. This means changing your mindset so that the code you write now, will have a better chance to be issue-free later on.

    We now need to approach our code with the assumption that magic quotes are no longer active. If they just-so-happen to be enabled, you can remove the added slashes from the values so that you don't run the risk of double-escaping the values. Also, if your code is going to be run in an unknown environment, you can apply added protection so that it still works as-per-normal, or even dies with an appropriate error message.

    Code php:
    if (get_magic_quotes_gpc()) {
        $email = stripslashes($email);
    }

    If you don't want to perform such checks for each variable, you can instead exit out of your code stating that "no magic quotes" is a requirement for your code. That way you can ensure that your code only runs in an environment that doesn't have magic quotes.

    When it comes to disabling magic quotes, there are many techniques available. My favourite being to disable them completely at the server.

    The preferred order of preference for disabling magic quotes is:

    Code:
                      PHP 5.2  PHP 5.3  PHP 6.0
    php ini settings     1       N/A      N/A
    .htaccess            2        1       N/A
    runtime code         3        2       N/A
    3. Handling values

    The values that you now have must still be considered to be untrusted, and potentially dangerous. When these values are passed to the database they may contain attempted SQL Injection code, and when passed to the web page they may contain XSS code. Your code needs to now treat them as untrusted values, as they came from an untrusted source, the user. This is not to say that they will contain bad values. It's only to say that there exists the potential for bad values.

    While there are some ways to protect against bad values when getting input values, the only effective way to provide proper protection is to make sure that the values are safe during the output process, whether that be to the database, the web page, or other places like email, XML, files, url, etc.

    4. Protect the database



    As of PHP version 5.5 the MySQL functions have been Deprecated and should no longer be used.
    all mysql_ functions
    http://php.net/manual/en/migration55.deprecated.php
    ext/mysql deprecation

    The original MySQL extension is now deprecated, and will generate E_DEPRECATED errors when connecting to a database. Instead, use the MySQLi or PDO_MySQL extensions.




    Sending values to the database is fraught with issues, but if you ensure that your database values are escaped only once, you should be safe. The appropriate ways to do that are to use mysql_real_escape_string at the database query itself, as in the example on the mysql_real_escape_string documentation page, or by using prepared statements with for example, mysqli_prepare.

    5. Output to the page

    Functions such as htmlspecialchars and htmlentities are useful for outputting values to the page. The former only converts ampersands, double quotes and angled brackets, which provides a useful minimum of protection. The latter function converts every single character that has an html entity equivalent, which can sometimes be considered to be too heavy-handed.

    Code php:
    echo 'An email has been sent to you at ' .
       '<strong>' . htmlspecialchars($email) . '</strong>';
    Last edited by Mittineague; Aug 2, 2013 at 19:13.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


Bookmarks

Posting Permissions

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