mysql_real_escape_string , where should i put it?

I dont really understand where i should implement this.

In my login function for example, where do i put this?

<?php
include('includes/functions.php');
session_start();

if(isset($_POST['login'])) {
	if(isset($_POST['username'])) {
		if(isset($_POST['password'])) {
			$username = $_POST['username'];
			$query = mysql_query("SELECT * FROM users WHERE Username = '$username'") or die(mysql_error());
			$user = mysql_fetch_array($query);
			
			if(md5($_POST['password']) == $user['Password']) {
				echo "Login successful!";
				$_SESSION['user'] = $user['Username'];
				header("Location: index.php");
			} else {
				echo "Please check your login details!";
				include('login.php');
			}
		} else {
			echo "Please check your password!";
			include('login.php');
		}
	} else {
		echo "Please check your username!";
		include('login.php');
	}
} else {
	echo "Please check that you filled out the login form!";
	include('login.php');
}
?>

<?php
...
$username = escape($_POST['username']);
...

function escape( $str ) {
    $str = stripslashes($str);
    return mysql_real_escape_string($str);
}

?>

First, read what the function does :wink:

The mysql_real_escape_string() function escapes data going into the database, and as such it should be invoked upon the data before it is used in the query. In your snippet above, it would be applied onto the $_POST[‘username’] variable whilst being assigned to the $username variable. You may also want to take a look into filtering your input data, where you can limit the user’s input by validating the data entered. For example, if you’d only like usernames to contain alphanumerical characters, then you can use the ctype_alnum() function. These are basic concepts to enabling user input into your web application, and they are a necessity to learn.

In regards to your query, you could simplify the logic by querying for the username and password, and then use MySQL’s COUNT() function to return the number of rows selected. This will also be a more optimised method, because we firstly aren’t having to fetch all columns (using the * wildcard, which isn’t even needed), and secondly we aren’t requiring data to be returned; only the number of selected rows.

You may also want to look into a more modern API, such as MySQLi. In the MySQLi API, you can make use of another escaping method, prepared statements, along with much other functionality not seen in the original MySQL extension.

I’d personally avoid using the stripslashes() function, especially since this is user input, and we don’t want to deform it before storing it for data persistence. It’s a function that I’d only use if I knew that the HTML tags were well-formed (ie, stripping the already-parsed BBCode tags), and it would be applied upon data output. This is only really needed if you’re looking to give a preview of part of the text, where the HTML styling is not needed/wanted. Otherwise, I’d still opt to go with htmlspecialchars().

I think you miss the difference between stripslashes and striptags :slight_smile: stripslashes will just make sure that if magic_quotes_gpc is ON, we will not get a double-escape (for quotes).

Whoops, sorry. I misread it as striptags() for some reason or another. Because magic_quotes_gpc was deprecated in PHP 5.3, I don’t really think it’s overly necessary to strip the slashes beforehand though.

Also another reason to migrate away from the mysql_* extension is that the mysql_* extension is now deprecated as of the current version of php. An alternative extension to migrate over to is PDO

Hmm many people is telling me this, but my concern is, now i have spent ages building my little CMS, isnt it hard for me as a beginner in php and mysql to “convert” my code to mysli? Should i try to do it or check it out for my next project?

+1 for PDO. OOP is way better.

but my concern is, now i have spent ages building my little CMS, isnt it hard for me as a beginner in php and mysql to “convert” my code to mysli?

If it’s your project, you know better what’s there. However, PDO will show to you new limits :slight_smile:

Converting it to the procedural MySQLi API is simple because both APIs are very similar. Take the following script written with the original MySQL extension ([i][u]taken from a PHPMaster article[/u][/i]):


$db = mysql_connect('host', 'username', 'password');
mysql_select_db('database', $db);

$clean['name'] = mysql_real_escape_string($name);
$clean['email'] = mysql_real_escape_string($email);

mysql_query("INSERT INTO table_name VALUES (NULL, '{$clean['name']}', '{$clean['email']}')");

mysql_query("UPDATE table_name SET name = 'Thomas' WHERE email = '{$clean['email']}'");

$result = mysql_query("SELECT name FROM table_name WHERE email = '{$clean['email']}'");

if ($row = mysql_fetch_assoc($result)) {
     echo $row['name'];
} else {
     echo 'No results found.';
}

And then convert it to the MySQLi API:


$db = mysqli_connect('host', 'username', 'password');
mysqli_select_db($db, 'database');

$clean['name'] = mysqli_real_escape_string($db, $name);
$clean['email'] = mysqli_real_escape_string($db, $email);

mysqli_query($db, "INSERT INTO table_name VALUES (NULL, '{$clean['name']}', '{$clean['email']}')");

mysqli_query($db, "UPDATE table_name SET name = 'Thomas' WHERE email = '{$clean['email']}'");

$result = mysqli_query($db, "SELECT name FROM table_name WHERE email = '{$clean['email']}'");

if ($row = mysqli_fetch_assoc($result)) {
     echo $row['name'];
} else {
     echo 'No results found.';
}

Aside from the changing of mysql_* to mysqli_*, the only real difference is that we are forced to pass the connection argument as the first parameter to the mysqli class functions (the first table), as opposed to the optional passing of it as the second argument in the original MySQL extension.

So is it pretty much adding and “i” to all “mysql” ???