Yeah, as mentioned the prepared statements are a much better option. Since you are already using MySQLi, you can write the prepared statements with little changes.
Lets do a quick example without functions of what you would do with just the query:
PHP Code:
if (ini_get('magic_quotes_gpc')) { $_POST['username'] = stripslashes($_POST['username']); } $username = mysqli_real_escape_string($_POST['username']); mysqli_query($dblink,"INSERT INTO cms_users VALUES (NULL,'".$username."')");
And the same using a bind (I'll use OO and procedural here):
PHP Code:
if (ini_get('magic_quotes_gpc')) { $_POST['username'] = stripslashes($_POST['username']); }
$username = $_POST['username']; // do whatever validation you need to do.
// Always need the check for magic_quotes until 5.4 is mainstream minimum version if ($stmt = mysqli_prepare($dblink, "INSERT INTO cms_users VALUES (null, ?)")) { mysqli_stmt_bind_param($stmt, 's', $username); mysqli_stmt_execute($stmt); mysqli_stmt_close($stmt); }
// OO if ($stmt = $dblink->prepare("INSERT INTO cms_users VALUES (null, ?)")) { $stmt->bind_param('s', $username); $stmt->execute(); $stmt->close(); }
That indicates you are inserting htmlentites and line breaks into your storage. Use htmlentities during display to parse any HTML if you allow it in, and nl2br if you require non-breaking spaces. Don't save the data like this, keep it in its pure form. If you are not wanting HTML at all, you can use strip_tags.
Yeah, as mentioned the prepared statements are a much better option. Since you are already using MySQLi, you can write the prepared statements with little changes.
Lets do a quick example without functions of what you would do with just the query:
PHP Code:
if (ini_get('magic_quotes_gpc'))
{
$_POST['username'] = stripslashes($_POST['username']);
}
$username = mysqli_real_escape_string($_POST['username']);
mysqli_query($dblink,"INSERT INTO cms_users VALUES (NULL,'".$username."')");
And the same using a bind (I'll use OO and procedural here):
PHP Code:
if (ini_get('magic_quotes_gpc'))
{
$_POST['username'] = stripslashes($_POST['username']);
}
$username = $_POST['username']; // do whatever validation you need to do.
// Always need the check for magic_quotes until 5.4 is mainstream minimum version
if ($stmt = mysqli_prepare($dblink, "INSERT INTO cms_users VALUES (null, ?)"))
{
mysqli_stmt_bind_param($stmt, 's', $username);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
}
// OO
if ($stmt = $dblink->prepare("INSERT INTO cms_users VALUES (null, ?)"))
{
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->close();
}
That indicates you are inserting htmlentites and line breaks into your storage. Use htmlentities during display to parse any HTML if you allow it in, and nl2br if you require non-breaking spaces. Don't save the data like this, keep it in its pure form. If you are not wanting HTML at all, you can use strip_tags.
Not to insert i'm using filter() and to output i'm using clean()
Oh then that's okay yeah. Except for the stripslashes, that should be dealt with before it hits storage (its only an issue if magic_quotes_gpc is running and you execute an escape sequence on the inserted data). Magic quotes runtime can be disabled at runtime, so before you select simply issue an ini_set('magic_quotes_runtime', 0); just in case its enabled (also gone as of 5.4). Its corrupted the data if you allow slashes where the do not belong. IE, if I specify a filepath of \\machine\c$, then that would be \\\\machine\\c$ which isn't what I asked for. Strip them out, then sanitize (or don't sanitize and issue a bind). MySQL itself will receive \\\\machine\\c$ as its input type (from the escape string call), but that is to perform the proper escapes to the data itself whilst inserting. If I use both magic quotes and escape, I'd end up with \\\\\\\\machine\\\\c$ as its going in, so that would give me \\\\machine\\c$ once inserted into storage. If that all makes sense. I'm *quite* sure that addslashes on top of addslashes will escape regardless of escaped status, but running in writecodeonline.com issues a \\machine\\c$ on a single addslashes where I'd expect that it should be \\\\machine\\c$ (and codepad is down :/).
Also, checking on the api, get_magic_quotes_gpc() function does not appear to deprecate. Which is perfect; that is a better option IMO than ini_get. ini_get if overridden during .htaccess level using 'on' instead of 1 or true will result in ini_get failing to provide the proper information on the magic_quotes_gpc. I swapped to using ini_get awhile ago since I wasn't sure what zend was planning when it came to removing magic_quotes (which I actually thought wouldn't happen until 6.0, but here we are).
Oh then that's okay yeah. Except for the stripslashes, that should be dealt with before it hits storage (its only an issue if magic_quotes_gpc is running and you execute an escape sequence on the inserted data). Magic quotes runtime can be disabled at runtime, so before you select simply issue an ini_set('magic_quotes_runtime', 0); just in case its enabled (also gone as of 5.4). Its corrupted the data if you allow slashes where the do not belong. IE, if I specify a filepath of \\machine\c$, then that would be \\\\machine\\c$ which isn't what I asked for. Strip them out, then sanitize (or don't sanitize and issue a bind). MySQL itself will receive \\\\machine\\c$ as its input type (from the escape string call), but that is to perform the proper escapes to the data itself whilst inserting. If I use both magic quotes and escape, I'd end up with \\\\\\\\machine\\\\c$ as its going in, so that would give me \\\\machine\\c$ once inserted into storage. If that all makes sense. I'm *quite* sure that addslashes on top of addslashes will escape regardless of escaped status, but running in writecodeonline.com issues a \\machine\\c$ on a single addslashes where I'd expect that it should be \\\\machine\\c$ (and codepad is down :/).
Also, checking on the api, get_magic_quotes_gpc() function does not appear to deprecate. Which is perfect; that is a better option IMO than ini_get. ini_get if overridden during .htaccess level using 'on' instead of 1 or true will result in ini_get failing to provide the proper information on the magic_quotes_gpc. I swapped to using ini_get awhile ago since I wasn't sure what zend was planning when it came to removing magic_quotes (which I actually thought wouldn't happen until 6.0, but here we are).
So i could remove stripslashes() as long as i've disabled;
That's right. Since magic_quotes_runtime is also gone, its easier to simply disable that and go from there. Ini is nice since if you set an invalid value (such as magic_quotes_runtime in 5.4+), it doesn't actually cause an error.
Don't do this: global $db; . Globalization is problematic to debug, especially since it will never trigger an error should the variable not be declared. Pass $db to the function as an argument instead. If you choose OO approach, you can signature the datatype with public function filter($string, MySQLi $db);. Reserve global for only when you cannot alter the signature of the function.
That's right. Since magic_quotes_runtime is also gone, its easier to simply disable that and go from there. Ini is nice since if you set an invalid value (such as magic_quotes_runtime in 5.4+), it doesn't actually cause an error.
Don't do this: global $db; . Globalization is problematic to debug, especially since it will never trigger an error should the variable not be declared. Pass $db to the function as an argument instead. If you choose OO approach, you can signature the datatype with public function filter($string, MySQLi $db);. Reserve global for only when you cannot alter the signature of the function.
Ok, thankyou, i have a better understanding of this now thanks.