I’m trying to insert values in the contents table. It works fine if I do not have a PHP variable inside VALUES. When I put the variable $type inside VALUES then this doesn’t work. What am I doing wrong?
$type = 'testing';
mysql_query("INSERT INTO contents (type, reporter, description)
VALUES($type, 'john', 'whatever')");
The rules of adding a PHP variable inside of any MySQL statement are plain and simple:
1. Use prepared statements
This rule covers 99% of queries and your query in particular. Any variable that represents an SQL data literal, (or, to put it simply – an SQL string, or a number) MUST be added through a prepared statement. No exceptions. A constant value can be put as is.
This approach involves four basic steps
And here is how to do it with all popular PHP database drivers:
Adding data literals using
mysqliStarting from PHP 8.2 you can do the entire prepare/bind/execute sequence in one call:
If your PHP version is old, then prepare/bind/execute has to be done explicitly:
The code is a bit complicated but the detailed explanation of all these operators can be found in my article, How to run an INSERT query using Mysqli, as well as a solution that eases the process dramatically.
For a SELECT query you can use the same method as above:
but again, if your PHP version is old, you will need to go through prepare/bind/execute routine and also add a call to
get_result()method, in order to get a familiarmysqli_resultfrom which you can fetch the data the usual way:Adding data literals using PDO
In PDO, we can have the bind and execute parts combined, which is very convenient. PDO also supports named placeholders which some find extremely convenient.
2. Use white list filtering
Any other query part, such as SQL keyword, table or a field name, or operator – must be filtered through a white list.
Sometimes we have to add a variable that represents another part of a query, such as a keyword or an identifier (a database, table or a field name). It’s a rare case but it’s better to be prepared.
In this case, your variable must be checked against a list of values explicitly written in your script. This is explained in my other article, Adding a field name in the ORDER BY clause based on the user’s choice:
Here is an example:
After such a code, both
$directionand$orderbyvariables can be safely put in the SQL query, as they are either equal to one of the allowed variants or there will be an error thrown.The last thing to mention about identifiers, they must be also formatted according to the particular database syntax. For MySQL it should be
backtickcharacters around the identifier. So the final query string for our order by example would be