I'm seeing a few common coding oversights occur in these forums which I would like to address to help people out. Before I do, I just want to expand on some of the topics Steveo31 talks about above. Use your browsers find/search feature to pinpoint specific information in this post.
$_GET Variables – for PHP version 4.1.0 or higher.
You can use $_REQUEST instead of $_GET or $_POST variables. The $_REQUEST will work with either a get or post form submission method. By using $_REQUEST means you would not have to change your code later in the event the HTML form submission method changes.
I should point out that the PHP manual recommends that you use $_GET or $_POST directly so you know exactly where the data is coming from. I think with register_globals turned off that it's alright to use $_REQUEST (which also contains $_COOKIE data too).
Refer to: http://www.php.net/reserved.variables#rese...riables.request
For reference: http://www.php.net/variables.external
Session Errors – or about getting the "headers already sent" warning messages.
The "headers already sent" warning messages can also happen with setcookie(), header(), and mail() function uses and not just session_start(). All these type of functions need to send headers to the browser before your script outputs anything to the browser. The session_start() (and these other functions) don't necessarily have to go at the very top of a script (although it's recommended). They can go anywhere in a script as long as your script has not yet sent ANYTHING to the browser before one of these functions is executed. By 'anything' I mean non-header data like HTML/non-HTML, and no whitespaces like spaces, tabs, newlines, carriage returns, formfeeds, hidden (non-visible) characters, etc.
It's alright to have include/require files before issuing these header related functions, but again, the included file(s) must not have code that sends anything to the browser. The problem could be in the main script or found in the included file(s). Most often there are usually one or more spaces found before the opening "<?PHP" tag, or spaces and newlines after the ending "?>" PHP tag. That's all it takes; these would output to the browser as non-header data and will cause the "headers already sent" warning messages to be issued. Remember that a PHP script is by default a HTML file first and foremost and that's why we use PHP tags; to distinguish between HTML and PHP code. Anything not in PHP tags is considered HTML and is output to the browser (even if it's a single space).
The link below talks more about this topic. When you just can't find where you're outputting stuff to the browser accidentally, then I recommend you use the ob_start() function on the first line in your script. This starts output buffering which buffers non-header data sent to the browser. This will prevent the "headers already sent" warning messages. The ob_start() option should be looked at as a band-aid and not as a solution. The real solution is to locate in your script file(s) where you are sending data to the browser prematurely.
Read about how to locate whitespaces in your script by following the links found here:
http://www.phpfreaks.com/forums/index.php?...=0entry146490
MySQL Data Retrieval
A very common problem I see on these forums is that some people are not checking for errors after an SQL query. You need to check for a good return (no errors) before performing any subsequent SQL related commands (such as a fetch or number of rows). Also, you must check if you got data back after attempting to retrieve the data; do not just start using the row data blindly. Good coding practice never assumes there will be data returned. Example:
// Connect to MySQL server first – You can use variables instead of these literals
$db = mysql_connect('localhost', 'username', 'password');
if (!$db) {
echo 'Could not connect to MySQL server. <br />Error # ', mysql_errno(), ' Error msg: ', mysql_error();
exit;
}
// Select the database you want to use – You can use a variable here too instead
if (!mysql_select_db('DBname', $db)) { // Did selection fail?
// Handle error
echo 'DB Selection failed. <br />Error # ', mysql_errno(), ' Error msg: ', mysql_error();
exit;
}
// An example for retrieving zero or more rows
$sql = "SELECT name, email FROM people_table";
$result = mysql_query($sql, $db);
if (!$result) {
// Handle error
echo 'Query failed. SQL: ', $sql, '<br />Error # ', mysql_errno(), ' Error msg: ', mysql_error();
exit;
}
// The while loop stops when there's no data left; it might not even go in loop
// and echo anything when there's no data returned on the first call to
// mysql_fetch_assoc()
while($row = mysql_fetch_assoc($result)) { // Retrieve data until no more
echo $row['name'], '<br />';
echo $row['email'], '<br />';
}
// Optional – Free up memory. Done automatically when script ends
if (!mysql_free_result($result)) {
// Handle error or ignore it
echo 'Freeing results failed. <br />Error # ', mysql_errno(), ' Error msg: ', mysql_error();
exit;
}
// Once the results table is freed, don't attempt to use the $result variable anymore
//****************************************************************
// For retrieving zero or one row (the first row with that name)
$name = mysql_escape_string('John Doe'); // or use addslashes()
$sql = "SELECT email FROM people_table WHERE name = '$name'";
$result = mysql_query($sql, $db);
if (!$result) {
// Handle error
echo 'Query failed. SQL: ', $sql, '<br />Error # ', mysql_errno(), ' Error msg: ', mysql_error();
exit;
}
$row = mysql_fetch_assoc($result); // Try to retrieve the data
if (!$row) // No data returned?
// Not necessarily an error – Just no data matched search criteria
echo 'No data found <br />';
else // There is valid data returned
echo "The email for $name is ", $row['email'], '<br />';
// Optional – Close MySQL connection. Will be closed at end of script anyway
// Do NOT put a mysql_close() after a query and before fetching data!
if (!mysql_close($db)) {
echo "Couldn't close database <br />"; // or ignore error
exit;
}
Note that some people use die(), which is simply an alias of exit().
I've also seen this type of poor coding:
$nbr = mysql_num_rows(mysql_query("SELECT name, email FROM people_table"));
// or
$row = mysql_fetch_assoc(mysql_query("SELECT name, email FROM people_table WHERE id = '$id'"));
Never enclose one MySQL function inside another like that. As already explained, a query could return an error and a valid results resource won't exist (or be returned). This would then cause the outer function to fail with a "not a valid MySQL result resource" message (see the Annoying Errors section below).
TIP: You can make the formatting of SQL statements a little bit easier by using arrays and the sprintf() function. One array could hold all the column names you have in a table. Like this:
$columns = array('catg_id', 'catg_description');
You can even find out what the column names are dynamically and place the column names in an array producing the same result as above. In the following example, the first '%s' in sprintf() will be replaced with '*' and the second '%s' will get replaced with 'categories'. Here's the example:
// An example to automatically get column names
$sql = sprintf('SELECT %s FROM %s LIMIT 1',
'*',
'categories'
);
echo 'COLUMN NAME SELECT SQL: ', $sql, '<br>';
$result = mysql_query($sql);
if (!$result) {
echo 'Query failed. SQL: ', $sql, '<br>Error: ', mysql_error(), '<br>';
exit;
}
$row = mysql_fetch_assoc($result); // Retrieve the one row
if (!$row) // No data found?
// Set columns manually or display error (and exit)
$columns = array('catg_id', 'catg_description');
else
// Convert associate keys into values
$columns = array_keys($row);
echo '<pre>', print_r($columns, TRUE), '</pre>';
The above code would display something like this:
Inserting data into a table can be easier with having a columns array and a values array. Then using implode() to handle the formatting of commas and generating the SQL. This is especially handy when you have lots of column names in your table. Example:
// Escape characters when necessary and surround value with quotes
function quote($_value = '', $_check_gpc = TRUE) {
if (($_check_gpc) &&
(get_magic_quotes_gpc()))
return ("'" . $_value . "'");
else
return ("'" . mysql_escape_string($_value) . "'");
}
/*
* You can create arrays to hold table and column names
*/
$tables = array('categories'); // Doesn't have to be an array
$columns = array('catg_id', 'catg_description');
/*
* Build an array of values to place in table
* The order of values needs to correspond to column(s) order given
*/
$values = array(); // Initialize
$values[] = quote(''); // catg_id blank - auto increment
$values[] = quote($_POST['catg']); // New category – Contains: Cameras
/*
* Use sprintf() to nicely take care of building the SQL statement
*/
$sql = sprintf('INSERT INTO %s (%s) VALUES (%s)',
implode (', ', $tables),
implode (', ', $columns),
implode (', ', $values)
);
echo 'INSERT SQL: ', $sql, '<br>';
$result = mysql_query($sql);
if (!$result) {
echo 'Insert failed. SQL: ', $sql, '<br>Error: ', mysql_error(), '<br>';
exit;
}
$last_id = mysql_insert_id(); // Get last auto increment id used
echo 'Last insert id: ', $last_id, '<br>';
Which displays something like this:
The update SQL is a little trickier because we have two separate arrays that hold the column name and values. You could have one array where the keys of the array are the names of the columns and the values would of course be what you want to update or modify. This sample code uses two separate arrays for column and values. When you're table contains an auto increment column, then you probably don't want to change it's value. So, this code removes it so it won't get updated. See example code:
// Returns column_name = 'value' for update SQL
function kv_pair($_key = array(), $_value = array()) {
$_result = '';
$_key_cnt = count($_key);
$_value_cnt = count($_value);
if (($_key_cnt > 0) &&
($_key_cnt == $_value_cnt)) {
$_result = array();
for ($i = 0; $i < $_key_cnt; $i++)
$_result[] = $_key[$i] . ' = ' . quote($_value[$i]);
$_result = implode(', ', $_result);
}
return $_result;
}
$without_id = $columns; // Copy original columns array
$id = array_shift($without_id); // Remove first catg_id entry
$values = array(); // Initialize
$values[] = 'Books'; // Change category description to Books
$where = array(); // Initialize
$where[] = $columns[0] . ' = ' . quote($last_id); // catg_id = 'last number'
$operator = ''; // Just one condition; no need for operator
$sql = sprintf('UPDATE %s SET %s WHERE %s',
implode (', ', $tables),
kv_pair($without_id, $values), // returns a string
implode (" $operator ", $where)
);
echo 'UPDATE SQL: ', $sql, '<br>';
$result = mysql_query($sql);
if (!$result) {
echo 'Update failed. SQL: ', $sql, '<br>Error: ', mysql_error(), '<br>';
exit;
}
The update code displays something like:
Generating the select SQL is pretty simple using this method. See example code:
$where = array();
$where[] = $columns[0] . ' = ' . quote($last_id); // Need ID or description
$where[] = $columns[1] . ' = ' . quote('Books'); // but using both to show AND
$operator = 'AND';
$sql = sprintf('SELECT %s FROM %s WHERE %s',
implode (', ', $columns),
implode (', ', $tables),
implode (" $operator ", $where)
);
echo 'SELECT SQL: ', $sql, '<br>';
$result = mysql_query($sql);
if (!$result) {
echo 'Query failed. SQL: ', $sql, '<br>Error: ', mysql_error(), '<br>';
exit;
}
while ($row = mysql_fetch_assoc($result))
echo '<pre>', print_r($row, TRUE), '</pre>';
The select code above would display something like this:
Here's an example of a select SQL using two tables:
$tables = array('categories', 'inventory');
$columns = array('catg_id', 'catg_description',
'inv_in_stock', 'inv_description', 'inv_price');
$where = array();
$where[] = $tables[0] . '.' . $columns[0] . ' = ' .
$tables[1] . '.' . $columns[0];
$where[] = $columns[1] . ' = ' . quote('Books');
$operator = 'AND';
$columns[0] = $tables[0] . '.' . $columns[0]; // make into categories.catg_id
$sql = sprintf('SELECT %s FROM %s WHERE %s',
implode (', ', $columns),
implode (', ', $tables),
implode (" $operator ", $where)
);
echo 'SELECT SQL: ', $sql, '<br>';
$result = mysql_query($sql);
if (!$result) {
echo 'Query failed. SQL: ', $sql, '<br>Error: ', mysql_error(), '<br>';
exit;
}
while ($row = mysql_fetch_assoc($result))
echo '<pre>', print_r($row, TRUE), '</pre>';
The select code above would display something like this:
Variables
With the 'register_globals' php.ini configuration setting off, variables defined in your form will not be accessible by their name (i.e. $name, $address, $phone, $email, etc.). You can use the $_REQUEST superglobal array variable with the index being the name defined in your HTML form (i.e. $_REQUEST['name'], $_REQUEST['address'], $_REQUEST['phone'], $_REQUEST['email'], etc.).
This is also true about other PHP variables and functions that rely on 'register_globals' being on. Like $PHP_SELF won't be created and session_register() won't work with 'register_globals' set to off. For these instances, use $_SERVER['PHP_SELF'] and $_SESSION variables instead.
Filter get/post form data example:
http://www.phpfreaks.com/forums/index.php?...=0entry130786
Slashes, quotes, and line breaks, oh my!
It's important to know the settings of 'magic_quotes_gpc' and 'magic_quotes_runtime' php.ini settings before using addslashes(), mysql_escape_string(), or stripslashes() on variable data obtained from a HTML form, file or database. Usually the 'magic_quotes_gpc' is on, and 'magic_quotes_runtime' is off. You can find out their settings from within a script by using get_magic_quotes_gpc() and get_magic_quotes_runtime() functions. When these settings are on, PHP has already done the addslashes() for you. Don't arbitrarily do an addslashes() to variables because you could end up having everything double slashed. Do something like this instead:
$last_name = isSet($_REQUEST['last_name']) ? $_REQUEST['last_name'] : '';
if (!get_magic_quotes_gpc()) // When off, do escape
$last_name = mysql_escape_string($last_name); // or use addslashes()
// Here you can add to the table or file fine now
Similarly, after reading from a file or table do not just do stripslashes() routinely because you may strip something in your data that you want to keep. PHP will only do addslashes() to values obtained from a file or table when the 'magic_quotes_runtime' setting is on. Check the setting and do something like this (a database example):
// Do the query and check for errors. The row has O'Brien for a value
while($row = mysql_fetch_assoc($result)) {
if (get_magic_quotes_runtime()) // O\'Brien will be returned
echo stripslashes($row['last_name']); // Strip the backslash
else
echo $row['last_name']; // O'Brien will display fine
}
You don't see that kind of handling a lot because 'magic_quotes_runtime' is usually off by default. However, I recommend that you don't rely on it being off and check for it as shown, or set it off using set_magic_quotes_runtime() function.
Note that the mysql_escape_string() function does a little more than the addslashes().
The differences between addslashes() and mysql_escape_string():
http://www.phpfreaks.com/forums/index.php?...=0entry138149
Decrypting MD5
There isn't any particular MD5 decryption functions, however, the MD5 hashes can be broken (not quickly but it can be done). I don't recommend using it for passwords and other important or sensitive information. Use the libmcrypt extension instead. Use long keys and make sure you store the key off the web or public directory at your site. If you can't install the libmcrypt extension, then you can use a home grown type of encryption and decryption routines. Here is one:
http://www.phpfreaks.com/quickcode.php?cmd=viewcode&id=309
With sample output found at:
http://www.phpfreaks.com/forums/index.php?...ndpost&p=133936
I was debating whether to provide the following information/links or not. I decided to present it to warn people about the use of MD5 and since the information are already readily available on the internet.
You can download a Windows program that cracks MD5 hashes:
http://members.cox.net/geno023/MD5Cracker.zip
Here's a PHP command prompt script that cracks MD5 hashes and keys:
http://www.securiteam.com/tools/5XP0X0040G.html
You can even submit an MD5 to be cracked online for free here:
http://www.passcracking.com
Project RainbowCrack:
http://www.antsight.com/zsl/rainbowcrack/
Password guessing:
http://packages.debian.org/testing/admin/crack-md5
A 2004 Article on the MD5 (and SH-0, SH-1) vulnerability:
http://www.technewsworld.com/story/35926.html
Cracking MySQL's MD5() function:
http://alan.blog-city.com/cracking_mysqls_...hin_seconds.htm
Dates and Times in MySQL
Read the MySQL date and time functions manual page. It's got lots of info. Here are a few forum post links related to MySQL date and time functions:
To find rows older than a certain number of day's example:
http://www.phpfreaks.com/forums/index.php?...=0entry151885
To add days to a date (note: to subtract you can use DATE_SUB instead):
http://www.phpfreaks.com/forums/index.php?...=0entry148927
To subtract months and/or years from a date:
http://www.phpfreaks.com/forums/index.php?...=0entry178059
Extracting the month from a date and making it into English:
http://www.phpfreaks.com/forums/index.php?...=0entry147338
Extracting the month, day, and year from a column:
http://www.phpfreaks.com/forums/index.php?...=0entry145177
An example of using 'BETWEEN' with date columns:
http://www.phpfreaks.com/forums/index.php?...=0entry144421
Annoying Errors
Regarding this type of messages:
Steveo31 is correct in that these messages are usually attributed to wrong SQL syntax in the query (or not connected to the database). What I mean by wrong syntax includes the possibility of using the wrong table or column names, and not just syntactically incorrect formatting of the query. This message can be avoided altogether; it masks/hides the real error at the query and is a by-product of wrong logic. These messages occur because error checking wasn't performed after a query and a subsequent SQL command was issued to work on the query result (when there was already a query error). This goes back to what I was explaining in the MySQL Data Retrieval section above (which has examples of correct MySQL error checking). You must check for errors and when there are errors, don't execute any more SQL commands that retrieve data or require the use of the results table. Handle the error after a query appropriately and your code logic shouldn't get as far as trying to read or examine the data inappropriately, then this warning message won't ever occur again. You need to display the real error that caused the query to fail in order for you to solve the main problem (which is usually bad SQL query syntax). Not handling errors like this is a serious logic flaw in code and I see it all the time. A big part of coding is really error checking. Don't get lazy or forget to check for errors.
Here's a few more Q & A's I'd like to share:
Q: Why do I get a "Notice: Undefined …" type of messages?
A: Sample code:
$first_name = $_REQUEST['first_name'];
The above code example would generate the following type of notice message only when the error_reporting() allows E_NOTICE type of messages (error_reporting is also a php.ini setting):
Some people are surprised by these notices and think they are out right errors; and they perhaps didn't see the notices when they were testing on their local machine, but see them on their web host providers server (or vice versa). That's because of the difference in 'error_reporting' settings between the two servers. This type of notice messages means that there doesn't seem to be an index entry with 'first_name' and so PHP considers it undefined. One way to prevent this notice is to not assume that an array index is there and check for it specifically first using the isSet() function as in this example:
$first_name = isSet($_REQUEST['first_name']) ? $_REQUEST['first_name'] : '';
This uses the ternary comparison operator. The $first_name variable will be assigned the value of $_REQUEST['first_name'] if it contains something other than NULL. Otherwise, it will be initialized to an empty string (you can set this to be anything you want as a default).
While testing scripts, I recommend that you have the E_NOTICE type of error messages on to help find possible problem areas in your code. Then turn it off before using scripts in a production setting.
Also, this example of code:
$name .= 'Doe';
Will produce the following notice message:
The '.=' is concatenating the 'Doe' to the existing value found in $name. Since the $name variable has not been initialized to something first you may get unpredictable results. Make sure you set/initialize all variables before using the '.=' concatenation assignment. The following code example will not produce the notice since a straight equal assignment is used before the use of '.=':
$name = 'Jane ';
$name .= 'Doe';
echo $name; // Displays Jane Doe
Q: Do I really need to use quotes with associative array indexes?
A: Yes. I recommend to use this syntax $ary['something'] instead of $ary[something]. Here's an explanation of why to always use quotes in associative array indexes:
http://www.phpfreaks.com/forums/index.php?...=0entry143604
Q: I'm trying to do an equal comparison. Why does this piece of code always executes the first 'if' statement?
$value = 2;
if ($value = 1)
echo 'one'; // This gets displayed
elseif ($value = 2)
echo 'two';
A: The equal comparison operator in PHP requires two equal signs (==) and not just one (=). One equal sign is an assignment operator. In this case, the '1' was assigned to the $value variable at the first 'if' expression, and this made the expression evaluate to TRUE; causing the echo 'one' to be executed. With this type of code example, PHP produces no errors (when there's a variable name to the left of the equal sign). This makes debugging this kind of problem more difficult and time consuming. It's not always very apparent.
Here's a tip to avoid this problem in the future. Get used to coding the 'if' expression with the literal value first or to the left of the equal sign, like this:
$value = 2;
if (1 == $value)
echo 'one';
elseif (2 == $value)
echo 'two'; // This gets displayed
That way if you happen to make a mistake and put just one equal sign again, then PHP will give you a parse error. The code of '1 = $value' is invalid because PHP can't assign the contents of $value to '1' (a literal; it must be a variable). This could potentially save you lots of time in testing/debugging because you get an error alert.
Q: Why does this switch statement keep executing all my case statements?
A: Sample code:
switch ($choice) {
case '1' : echo 'one selected';
case '2' : echo 'two selected';
case '3' : echo 'three selected';
default: echo 'Invalid entry';
}
The logic will fall-through and execute the remaining case statements because there are missing 'break' commands. The 'break' will get you out of the switch statement (and others like for, foreach, while, do..while). Change the code to something like this:
switch ($choice) {
case '1' :
echo 'one selected';
break;
case '2' :
echo 'two selected';
break;
case '3' :
echo 'three selected';
break;
default:
echo 'Invalid entry';
break;
}
There's no need to use 'break' on the last (or default) entry but it helps for consistency, and if you happen to later add another case condition, then the 'break' will already be there and you won't run into any more fall-through logic problems.
Q: I get a parse error while using array variables inside double quotes, why?
A: Sample code:
echo "Hello $row['name'] <br>";
The PHP parser doesn't always recognize array variables in double quotes. It mostly has a hard time recognizing associative and multi-dimensional array variables. By surrounding the array variable in curly braces you're telling the PHP parser exactly where the variable name begins and ends (so it will recognize the variable and it won't give a parse error). The curly braces will not be displayed. Here are examples of different solutions:
echo "Hello {$row['name']} <br>"; // Curly braces example
echo "Hello ", $row['name'], " <br>"; // Separate by commas
echo "Hello " . $row['name'] . " <br>"; // It works but avoid (it's slower)
Note that PHP will not recognize any type of variable when enclosed in single quotes. i.e. echo 'Hello $name' will just display that as is, and not the value contained in the $name variable. See complex syntax example at:
http://us3.php.net/manual/en/language.type...parsing.complex
Q: I want to define an array with values, but is there a way to start a numeric index with something other than zero?
A: Yes. You can set a numeric array index to any number by doing something like: $ary[20] = 'twenty'. The following are examples using '=>' to set the index value:
$months = array( 1 =>
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December');
echo $months[8]; // Displays August
// Another example:
$nbrs = array(10 => 'Ten', 20 => 'Twenty', 30 => 'Thirty');
echo $nbrs[30]; // Displays Thirty
Q: I'm trying to add some values obtained from a HTML form and it's giving me the wrong total, why?
A: Remember that browsers return form values to the server and your script as string values (even if they look like numbers). Use type casting to insure that you are adding numbers and not dealing with strings. You can also use the intval() and floatval() functions to convert strings into integers and real numbers. Examples of type casting:
$value = (int) 10; // Integer
$amt = (float) 12.95; // Floating point number
$str = '20'; // A string value. Same as doing $str = (string) '20';
You can also refer to these posts:
http://www.phpfreaks.com/forums/index.php?...=0entry139257
http://www.phpfreaks.com/forums/index.php?...=0entry145730
Q: I've been told using count() in a 'for' loop is bad, why is that?
A: It's not bad per say, it's just that the 'for' loop will run a little longer needlessly because PHP has to execute the count() function on every loop iteration. Changing the code from something like this:
// $month is an array that contains the names of each month
for ($i = 1; $i <= count($month); $i++) // count() executed 12 times
echo $month[$i], '<br>';
To something like this makes the 'for' loop run as much as 45% faster:
// $month is an array that contains the names of each month
$cnt = count($month); // Only need to do once
for ($i = 1; $i <= $cnt; $i++) // Use the $cnt variable instead
echo $month[$i], '<br>';
Q: How can I make a function recognize a variable set outside of the function?
A: Within the function use the 'global' keyword followed by the variable name. Separate each variable with a comma when there's more than one variable to list. See:
http://www.phpfreaks.com/forums/index.php?...=0entry146772
http://www.phpfreaks.com/forums/index.php?...=0entry145393
Q: When defining a function and it's arguments, is there a way to assign the default value of an argument using a variable?
A: No. However, you can use constants as shown in this post:
http://www.phpfreaks.com/forums/index.php?...=0entry148219
Q: Do I need to put quotes around my search criteria in a 'WHERE' clause when it's only going to be a number?
A: Yes, you should. The MySQL manual explains this point well. See this post:
http://www.phpfreaks.com/forums/index.php?...=0entry152413
Q: My SQL query looks alright, yet I'm getting a MySQL syntax error, but why?
A: Check to make sure that you're not accidentally using a MySQL reserved word which would mess up your SQL syntax. For simplicity and clarity never try and use a MySQL reserved word for database, table, or column names. You can by using the backtick character, but why make it confusing on yourself and others? See this post which also contains two useful MySQL manual links:
http://www.phpfreaks.com/forums/index.php?...=0entry152392
http://www.phpfreaks.com/forums/index.php?...=0entry137385
Q: I'm using a MySQL function in a query and mysql_fetch_assoc() to read the data, but I can't get at the column data that I'm using the MySQL function on, help?
A: Use the 'AS' MySQL keyword to name what you want the result data column to be called. That name will be used as the index key of the associative array. Here's an example:
$sql = "SELECT MAX(price) AS highest_price FROM inventory";
$result = mysql_query($sql);
if (!$result) {
// Handle error
echo 'Query failed. SQL: ', $sql, ' Error: ', mysql_error();
exit;
}
$row = mysql_fetch_assoc($result);
if (!$row)
echo 'No data returned';
else
echo 'That highest price is $', $row['highest_price']; // name used in the 'AS'
Q: Is there a way I can know what the column names are in my MySQL table?
A: You can do a 'SELECT * FROM table_name LIMIT 1' type of SQL query and retrieve the data with a mysql_fetch_assoc(), which creates an associative array with the column names as the index of the array. Then you can do a 'foreach' loop to display the array keys which will be your column names of the table. See:
http://www.phpfreaks.com/forums/index.php?...=0entry151124
An example of using 'DESCRIBE' to obtain column information from a known table:
http://www.phpfreaks.com/forums/index.php?...=0entry137926
Q: How can I add a column to an existing MySQL table?
A: The 'ALTER' SQL command can make lots of different types of changes to tables. For a link reference and a syntax use example see this post:
http://www.phpfreaks.com/forums/index.php?...=0entry143235
Q: I did my SQL query and it didn't find the row so I inserted a new row. Then I found out later that there are duplicates in my table. Why didn't it find my original row/data?
A: Sample code:
// The $email variable was set to something before this point. i.e '
[email protected]'
$sql = "SELECT CONCAT_WS(' ', first_name, last_name) AS user_name FROM user_table WHERE email = '$email'";
$result = mysql_query($sql);
if (!$result) {
// Handle error
echo 'Query failed. SQL: ', $sql, ' Error: ', mysql_error();
exit;
}
// Inserted new row here
The problem with the above code is that it was written with an assumption that it's alright to insert a new row because there was no error returned after the query. This is a costly mistake. A query can return no error but there may or may not be data waiting to be retrieved from the results table. You must use mysql_num_rows() to see if there are any rows in the results table, or retrieve the data with one of the many functions available, like mysql_fetch_assoc(). Only after doing one of these two methods will you really know if there is data that matched the search criteria (in the 'WHERE' clause) or not. I can't stress this point enough.
Now, the important missing code segment has been added in this example:
.
.
.
$result = mysql_query($sql);
if (!$result) {
// Handle error
echo 'Query failed. SQL: ', $sql, ' Error: ', mysql_error();
exit;
}
// Must fetch the data
$row = mysql_fetch_assoc($result);
if (!$row) {
echo 'No user found with that email address';
// It's now alright to insert a new row here
} else {
echo 'That email address is already being used by ', $row['user_name'];
}
Here's an example using the mysql_num_rows():
.
.
.
$result = mysql_query($sql);
if (!$result) {
// Handle error
echo 'Query failed. SQL: ', $sql, ' Error: ', mysql_error();
exit;
}
// See how many rows matched the search
$nbr_rows = mysql_num_rows($result);
if (0 == $nbr_rows) {
echo 'No user found with that email address';
// It's now alright to insert a new row here
} else {
// Can't display who already uses it because we haven't retrieved the data yet
echo "That email address is already being used by $nbr_rows member(s)";
}
In this case, having the email address column as being a non-duplicate index or primary key would also help. When an attempt to add a new row with an already existing email address, MySQL will not allow it and return a duplicate entry or key error.
Q: Is there another way of getting around escaping quotes all the time?
A: Sample code:
echo "<table><tr><td colspan=\"4\">Title: <input type=\"text\" name=\"group\" size=\"36\" maxlength=\"36\"></td></tr></table>";
This shows that all the double quotes in the string are escaped (\"). When you don't have any PHP variables inside the double quotes, then there's no need to start the string with double quotes. In this case, you can start the string with single quotes like this:
echo '<table><tr><td colspan="4">Title: <input type="text" name="group" size="36" maxlength="36"></td></tr></table>';
That makes it much easier to read and there's less typing. Whatever character you start the string with, single or double quotes, that same character must be escaped if it's contained within that string (but the other quote doesn't have to be).
Here are two options, when you use variables:
$group = 'group';
echo "<table><tr><td colspan='4'>Title: <input type='text' name='$group' size='36' maxlength='36'></td></tr></table>";
// or this way:
echo '<table><tr><td colspan="4">Title: <input type="text" name="', $group, '" size="36" maxlength="36"></td></tr></table>';
// or when assigning to a variable:
$table = '<table><tr><td colspan="4">Title: <input type="text" name="' . $group . '" size="36" maxlength="36"></td></tr></table>';
echo $table;
Some of my fellow colleagues may not approve of me letting you know about the heredoc syntax method. Some just don't like its use, but it is another option and I think you should know about it even if you may decide not to use it. You may come across scripts that use it and it's good to know what it is and its syntax. Heredoc examples:
http://www.phpfreaks.com/forums/index.php?...t=0entry48525
http://www.phpfreaks.com/forums/index.php?...t=0entry53197
The best option is to keep all HTML and JavaScript out of your PHP scripts (or at least as much as possible). By using Smarty template engine you can keep the HTML and JavaScript out of your PHP scripts. It does require a bit of a learning curve though. A note on Smarty:
http://www.phpfreaks.com/forums/index.php?...t=0entry48666
Q: How do I handle different Timezones and Daylight Savings Time?
A: An example of handling timezones:
http://www.phpfreaks.com/forums/index.php?...t=0entry59671
And in the same post, handling Daylight Savings Time:
http://www.phpfreaks.com/forums/index.php?...t=0entry59851
Q: Is there a way I can execute PHP code that's stored in a file or table?
A: Yes, by using the eval() function. See examples here:
http://www.phpfreaks.com/forums/index.php?...=0entry138271
http://www.phpfreaks.com/forums/index.php?...=0entry142651
Q: How do I calculate the elapsed time between two dates in PHP?
A: An example of a function to calculate the differences between two dates:
http://www.phpfreaks.com/forums/index.php?...t=0entry49857
Q: Is there a way to return more than one value back from a function?
A: Yes, and here is an example:
http://www.phpfreaks.com/forums/index.php?...=0entry140110
Q: Can an include/require file return a value?
A: Yes, and here's an example:
http://www.phpfreaks.com/forums/index.php?...t=0#entry132833
Q: Is there a way to set the include path within PHP and not the php.ini file?
A: Setting the include path with ini_set() example:
http://www.phpfreaks.com/forums/index.php?...=0entry148728
Q: How do I read all the filenames in a directory?
A: Here's a coding example that reads all the filenames in one directory and populates an array:
http://www.phpfreaks.com/forums/index.php?...=0entry147342
Q: The set_error_handler() is not able to handle parse errors. Is there a way to stop displaying parse errors and other types too?
A: See error handling example using output buffering (ob_start):
http://www.phpfreaks.com/forums/index.php?...=0entry139941
Q: Is there a pre-made PHP function to tell me if a number is odd or even?
A: No, not exactly. However, you can build your own small function. See code here:
http://www.phpfreaks.com/forums/index.php?...=0entry155723
Q: How do I retrieve just the 'index.php' from this /home/user/index.php path?
A: Use basename() function or use the 'basename' index returned from the array of pathinfo() function. See: http://www.php.net/manual/en/function.basename.php
http://www.php.net/manual/en/function.pathinfo.php
Q: How can I retrieve the different parts of a URL?
A: Use the parse_url() function. See: http://www.php.net/parse_url
Q: Is there any way to change my web host providers php.ini settings?
A: They most likely won't let you change the main php.ini file, however, if they're using the Apache server, then you may be able to override your web host providers settings using a .htaccess file. You use the Apache php_flag or php_value directives. Basically, create a .htaccess file and place it in the root or web directory and place the settings you want to change in it, like this:
php_flag register_globals off
php_flag magic_quotes_gpc off
php_flag session.use_trans_sid on
php_value session.gc_maxlifetime 600
php_value session.cookie_domain .example.com
php_value arg_separator.output &
php_value include_path .:/usr/lib/php:/usr/local/lib/php:/home/user/phplib
These settings remain permanent until you choose to change them again or delete the .htaccess file. See ini_set() too.