String performacne: PHP vs MySQL [duplicate] - php

This question already has answers here:
Doing calculations in MySQL vs PHP
(6 answers)
Closed 7 years ago.
Are there any performance concerns of note when using MySQL's CONCAT() function in a select query? Is it faster/slower/negligible to do a simple select, and format strings for a view using PHP after the result set from the database is returned? Or is a more complicated SQL query with multiple calls to CONCAT() that returns a string already formatted for the view a better approach?
ie is this:
select CONCAT(lastname, ', ', firstname) from people;
Faster/Slower/No difference from this:
<?php
$query = 'Select lastname, firstname from people';
...
$name = $data['lastname'] . ', ' . $data['firstname']; //OR
$name = sprintf("%s, %s", $data['lastname'], $data['firstname']);
?>

You're better off in almost all cases by doing filtering and data massaging with the SQL engine versus on the web server.

Unless you are planning to do hundreds of thousands such operations at once, it will not matter where you do the string concatenation from a performance point of view. The possible time savings will be so minuscule, they will probably not even be measurable.

Related

Comma-separated values doesn't work in PHP MYSQL [duplicate]

This question already has answers here:
Use an array in a mysqli prepared statement: `WHERE .. IN(..)` query [duplicate]
(8 answers)
Build SELECT query with dynamic number of LIKE conditions as a mysqli prepared statement
(2 answers)
Closed 11 months ago.
I'm currently facing a difficulty where putting a comma-separated values to a MySQL NOT IN doesn't give me the result I was hoping for. There must be something I'm missing as I'm unsure what to search for this particular problem. Running only the MySQL code works, but passing the parameter from another PHP function didn't.
Here's the code that's giving me a problem:
$uid = 1;
$selected_uids = '1,2';
$result = $db->retrieveFollowingWithCondition($uid, $selected_uids);
...then somewhere along the code...
public function retrieveFollowingWithCondition($uid, $selected_uids) {
$stmt = $this->conn->prepare("SELECT *
FROM `friendlist`
WHERE `uid` = ? AND `buddy_uid` NOT IN (?)
GROUP BY `buddy_uid`;");
$stmt->bind_param("is", $uid, $selected_uids);
...}
I've tested just putting '2' in $selected_uids and it actually works. But once there's comma involved, the code runs but the $selected_uids are still in the result. Not sure this is a bad practice or just needing a minor adjustment to the code. Anyway, I'm really looking forward to understand why it's not working for me.
By using s in bind_param you are telling PHP to treat the entire contents of $selected_uids as a string. Therefore, "1,2" is treated as ('1,2') instead of (1,2). Your problem is that bind_param doesn't support arrays, so support of IN queries is limited. There are a number of alternatives to get around this limitation, but since you are dealing with a list of ints, I would probably do a raw string concat.
// using is_numeric because is_int("1") === false
$filtered = array_filter('is_numeric', $selected_uids);
// You could also just call array_map('intval', $selected_uids);
// Depending on your needs.
if(!$filtered) {
return; // No valid values
}
$filteredStr = implode(',', $filtered);
$stmt = $this->conn->prepare("SELECT *
FROM `friendlist`
WHERE `uid` = ? AND `buddy_uid` NOT IN ($filteredStr)
GROUP BY `buddy_uid`;");
Should also be noted: if I were trying to use strings for an IN query, I would likely do the following:
$filtered = array_map([$this->conn, 'escape_string'], $queried);
$inQuery = '\'' . implode('\',\'', $filtered) . '\'';
I find that notation cleaner and easier than a dynamically generated bind_param format string.
You should bind every parameter in IN(...) separately, but method bind_param doesn't support multiple calls. There is a nice class that can do this and you can find it on PHP documentation pages:
Custom class for multiple bind_param

Preparing HTML Form Input for SQL Database using PHP [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 3 years ago.
I'm currently testing a html form which sends the data through php to the sql database. The problem I'm facing is special characters break the form and don't update the database. I haven't tested all the special characters but mainly ` and ' are the culprits. I've tried mysql_escape_string, preg_replace and add_slashes with no success. What am I missing?
$description = preg_replace('/[^A-Za-z0-9\ %&$=+*?()!.-]/', ' ', $_POST['description']);
$description = preg_replace("/[\n\r]/"," ",$description);
// Items Insert
foreach ($item as $index=>$value) {
$sqlItems .= "
INSERT INTO quote_items (quote_id, item, description, amount, gst)
VALUES ('$last_id', '$item[$index]', '$description[$index]', '$amount[$index]', '$gst[$index]');
";
}
Thanks in advance!
you can try this (a little dirty) but it should allow those 2 characters to be saved
$sqlItems .= '
INSERT INTO `quote_items` (quote_id, item, description, amount, gst)
VALUES ("'.$last_id.'", "'.$item[$index].'", "'.$description[$index].'", "'.$amount[$index].'", "'.$gst[$index].'");
';
EDIT: sorry had the quotes reversed
Can you post you DB call?
Those two characters in particular look like they would conflict in a DB call.
The ` is usually wrapped a table or column name
and the ' is usually wrapped around values.
Both of these would cause a problem but without code its hard to say

Getting empty query [duplicate]

This question already has answers here:
How to bind LIKE values using the PDO extension?
(7 answers)
Closed 7 years ago.
I'm trying to get a PDO query running, so I'm doing:
$src = $this->conn->prepare("SELECT name, model, software FROM product WHERE
model LIKE '%:search_string%' OR
name LIKE '%:search_string%' OR
software LIKE '%:search_string%'");
$src->bindParam(':search_string', $search_string);
$src->execute();
return $src->fetchAll();
But when I var_dump this, I always get an empty array ( [] ). However, if I change it to just "SELECT name, model, software FROM product", I get all of the products, just as expected, so how am I using the LIKE clause wrong? Or am I doing this completely wrong?
Bound parameters cannot be used in this way. You have to input it as LIKE :search_string in the prepared query, then add the percent signs in the bound value (i.e. $src->bindParam(':search_string', '%' . $search_string . '%');).
See also this comment on PDOStatement::bindParam.

Dynamically create contents of IN operator SQL php [duplicate]

This question already has answers here:
Can I bind an array to an IN() condition in a PDO query?
(23 answers)
Closed 7 years ago.
Is it possible to use prepared statements with either MySQLi or PDO and still be able to dynamically add items to the IN part of the query, for example...
$somearray = ['tagvalue1', 'tagvalue2', 'tagvalue3'];
$sql = "SELECT foo FROM bar
WHERE tag IN(?)";
I ask this because I have a situation whereby the number of elements in the IN part is not known until runtime.
You asked:
Is it possible to use prepared statements with either MySQLi or PDO
and still be able to dynamically add items to the IN part of the
query, for example...
No, unfortunately it is not. It happens that ColdFusion does this, but not php.
While you can't do exactly what you want with a prepared query, you can dynamically generate the $sql string for the query to accomplish the same thing.
Given some array $array = (n, n1, n2, ... nN)
$sql = "SELECT foo FROM bar WHERE tag IN (";
foreach($array as $value) {
$sql .= "'" . $value . "', ";
}
// Strip off the last comma and space from the IN clause
$sql = substr($sql, 0, strlen($sql) - 2);
$sql .= ")";
It's certainly not the most elegant solution and you'll have to do some more data validation or escaping of dangerous characters that a prepared query would handle better, but it will do the job.
As a side note, there are ORM (Object Relational Mapper) libraries that support things like accepting an array of values to generate the IN clause in a database statement. Propel is the one I have most experience with, but I'm sure others like Doctrine would have a similar method.
A propel-ish example would be like
$results = BarQuery::create()
->select('foo')
->filterByTag(array($value1, $value2, ..., $vauleN)
->find();
Lots of added functionality and support, but does increase your initial set up time for a project.

Protect SQL query from special characters [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 8 years ago.
I'm trying to change the content of a string (from user's input), I'd like to remove any character that will let my query fail. For example, if I insert a second name with a " ' " in it, the query will fail.
Since I have to then output these rows from the DB, I'm wondering if there's any way to insert the string in the database while replacing the special character with its HTML value so that when I'm outputting it, the browser will do the rest.
I'm leaving you an example:
$string = $_POST['user_input']; // Let it be Lol'd
$sql = "INSERT INTO table(field) VALUES('$string')";
Now without anything done to the string I'd get the query as:
INSERT INTO table(field) VALUES('Lol'd')
What I'm looking for is something to turn the ' into ' so that in the DB it's saved Lol'd but when I echo it it'll just print Lol'd
There are lot of solutions. You can use a function like htmlentities():
$string = htmlentities($_POST['user_input']); // Let it be Lol'd
$sql = "INSERT INTO table(field) VALUES('$string')";
To read the string from your MySQL table, use html_entity_decode()
try this
$string = str_replace("'","\'",$_POST['user_input']);
$sql = "INSERT INTO table(field) VALUES('$string')";

Categories