I have this query:
$sql = "
INSERT INTO table SET
name = '$name',
sku = '$number',
description = '$desc'
";
But the rows containing some special characters (in my case this ') are not inserted.. How I can solve?
Thanks in advance.
When you construct your query, you need to escape the data you are inserting.
You need to at least use addslashes() function in PHP, like this:
$sql = "INSERT INTO table SET name = '".addslashes($name)."', sku = '".addslashes($number)."', description = '".addslashes($desc)."'";
However more correct way is to use a different function than addslashes, which would properly handle all characters in the data, not only apostrophes.
I am using my custom 'escape' function like this:
function escape($text)
{
return str_replace(array('\\', "\0", "\n", "\r", "'", '"', "\x1a"), array('\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'), $text);
}
So using this function, you would write:
$sql = "INSERT INTO table SET name = '".escape($name)."', sku = '".escape($number)."', description = '".escape($desc)."'";
You must use parameterised queries instead of manually appending those values. Currently if name, number or description would contain any sql it would get executed.
A lot more detailed answer is in How can I prevent SQL injection in PHP?
Read about escaping characters in mysql. I think it is done with \
Related
I am new to python and currently learning to use SQL with python. I have the following code:
word = input("Enter a word: ")
query = cursor.execute("SELECT * FROM Dictionary WHERE Expression LIKE '%s%' " % word)
results = cursor.fetchall()
The second line throws an error since I don't think I can use '%s%' like that? How would I change this so as to be able to make this work? I want to be able to return all related entries to the users input. So if the user inputs "rain", then I want the query to return all possible results e.g. "raining", "rainy" etc. Thank you.
You can try
query = cursor.execute(f"SELECT * FROM Dictionary WHERE Expression LIKE '%{word}%' ")
You should use cursor.execute() parameter substitution rather than string formatting, to prevent SQL injection.
Then use CONCAT() to surround the search string with %.
query = cursor.execute("SELECT * FROM Dictionary WHERE Expression LIKE CONCAT('%', %s, '%' "), (word,))
for($count = 0; $count < count($_POST["item_sub_category"]); $count++)
{
$data = array(
':item_sub_category_id'
=> SELECT r_name FROM Repair where r_id = $_POST["item_sub_category"][$count]
);
$query = "INSERT INTO Repairlog (description,visitID) VALUES (:item_sub_category_id,'1')";
$statement = $connect->prepare($query);
$statement->execute($data);
}
As far as concerns, your code won't work. The SQL query that you are passing as a parameter will simply be interpreted as a string.
You could avoid the need for a loop by taking advantage of the INSERT INTO ... SELECT ... syntax. The idea is to generate an IN clause that contains all values that are in the array, and then run a single query to insert all records at once.
Consider:
$in = str_repeat('?,', count($_POST["item_sub_category"]) - 1) . '?';
$query = "INSERT INTO Repairlog (description,visitID) SELECT r_name, 1 FROM Repair WHERE r_id IN ($in)";
$statement = $connect->prepare($query);
$statement->execute($_POST["item_sub_category"]);
Note: it is likely that visitID is an integer and not a string; if so, then it is better not to surround the value with single quotes (I removed them in the above code).
TLDR; No.
Your question can be re-framed as: Can I write SQL code in php. The answer is NO. You can write the SQL code within a String type variable (or parameter) in php.
This is a general rule for any programming language, you cannot have multiple languages within the same file, as the language parser will not be able understand which syntax is that.
In order to embed a different language in another language, you need some kind of separator that will define when the new language or special type will start and when it will end.
I need to insert ~150 simple rows (an id, and a static status of 'discard'). I have a string of the ids:
'123', '234r', '345', '456xyz'...
What's the simplest way to insert rows using this string of ids?
It seems like maybe there's some way to split the string on commas and... create a temp table to ...? I don't know - it just seems like this is the kind of thing that MySQL often manages to pull off in some cool, expedient way.
An example how to do create an INSERT statement with a few lines of PHP:
<?php
// copy your string of ids into this variable
$input = "'123', '234r', '345', '456xyz'";
// modify next line to get your desired filename
$filename = 'insert.sql'
// modify next line to your table name
$insert_statement = "INSERT INTO your_table_name (id, status) VALUES \n" .
'(' . implode(", 'discard')\n(", explode(', ', $input)) . ", 'discard');\n";
file_put_contents($filename, $insert_statement);
?>
Note
This is for this special use case. If the string of ids contains some special characters like single quotes, then this simple approach will fail.
The one way is to create CSV file with appropriate records and upload it at once to mysql.
Please follow this tutorial: http://www.mysqltutorial.org/import-csv-file-mysql-table/
Got a question for you all...
What would be the best way to search my table by array, that has an array in the table.
EG:
$var = (1,4,7,9,14)
$Query = "SELECT * FROM business_listings WHERE category IN ($var)";
'category' would have 4,27,89,101
How can I get this to match if one of the numbers in the $var matches one of the numbers in the table.
If your database column is a list of comma separated values, and you're searching for one value in that list, then you're in a different situation.
If your category column contains the text value 410,406,149,152, like you commented below, and you're searching for fields whose category contains 152, then you'll need to use MySQL's FIND_IN_SET() function.
If you have to check multiple values, then you need to use more than one FIND_IN_SET. If you read the documentation, you'll see that the first argument for FIND_IN_SET must be a single string, not a string list (it can't contain a comma). Use the following instead:
$var = "401,320,152";
$items = explode(",", $var);
foreach ($items as &$i) {
$i = "FIND_IN_SET('" . $i . "', `category`)";
}
$search = implode(" OR ", $items);
unset($i);
$query = "SELECT * FROM business_listings WHERE " . $items;
This will output:
SELECT * FROM business_listings WHERE
FIND_IN_SET('401', `category`) OR
FIND_IN_SET('320', `category`) OR
FIND_IN_SET('152', `category`)
The above script will work even if $var contains only one value.
Finally, as tadman mentioned, since we're getting into queries that can be tricky to build with prepared statements, you need to make sure you're escaping and sanitizing your input properly. For an example, if $var is being retrieved from the user somehow, then before you modify it in any way, you need to escape it with mysqli_real_escape_string():
$var = $mysqli->real_escape_string($var);
Assuming that $mysqli is your open MySQLi connection.
Hope this helps!
I have the following query attempting an update in CodeIgniter:
$sql = "UPDATE fanout.manual_data
SET call_leader_id = ?
WHERE id IN (?)";
$q = $this->db->query($sql, array($leaderID, implode(", ", $empIDs)));
The implode is creating a string of all the IDs in my array. However, that is resulting in the query looking like:
UPDATE fanout.manual_data SET call_leader_id = '55993' WHERE id IN ('57232, 0097726, 0076034');
When what I need is:
UPDATE fanout.manual_data SET call_leader_id = '55993' WHERE id IN (57232, 0097726, 0076034);
Only difference, is the single quotes surrounding the string of IDs. Is this something I need to do myself and skip over CI's query bindings (http://codeigniter.com/user_guide/database/queries.html) or is something CI can handle and I'm just missing a step?
Thanks.
I don't think you can skip that behavior. You're technically passing a string, so CI interprets it as such and simply surrounds it with quotes.
I think you're better off simply concatenating the $empIDs by hand (e.g. using a foreach loop), escaping them with $this->db->escape() in case you wanna be sure.