well my function is this
function all_products($where, $condition, $where2, $condition2) {
$query = "SELECT *
FROM `product`
WHERE
".mysql_real_escape_string($where)." = '".mysql_real_escape_string($condition)."'
and
".mysql_real_escape_string($where)." = '".mysql_real_escape_string($condition)."'
";
$query_run = mysql_query($query);
return $query_run;
}
so whenever Im trying to use this function to fetch the data from db it returns rows even if only the $where and $condition is true and $where2 and $condition2 is false.
You can support variable length of conditions.
function all_products(array $assoc) {
foreach ($assoc as $key => $value) {
$pairs[] = sprintf(
"`%s` = '%s'",
addcslashes($key, '`'),
mysql_real_escape_string($value)
);
}
$sql = empty($pairs) ?
'SELECT NULL LIMIT 0' :
'SELECT * FROM `product` WHERE ' . implode(' AND ', $pairs);
return mysql_query($sql);
}
However, all mysql_* functions are already DEPRECATED. I strongly recommend you migrate to PDO or mysqli.
Related
Trying to get a function working to create simple CRUD "Select" with multiple parameters to any table. I think I got the hardest part, but couldn't fetch the data right now. Maybe I'm doing something wrong I can't figure out.
My prepared statement function:
function prepared_query($mysqli, $sql, $params, $types = ""){
$types = $types ?: str_repeat("s", count($params));
if($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param($types, ...$params);
$stmt->execute();
return $stmt;
} else {
$error = $mysqli->errno . ' ' . $mysqli->error;
error_log($error);
}
}
The query creator:
function create_select_query($table, $condition = "", $sort = "", $order = " ASC ", $clause = ""){
$table = escape_mysql_identifier($table);
$query = "SELECT * FROM ".$table;
if(!empty($condition)){
$query .= create_select_query_where($condition,$clause);
}
if(!empty($sort)){
$query .= " ORDER BY ".$sort." $order";
}
return $query;
}
The helper function to create the WHERE clause:
function create_select_query_where($condition,$clause){
$query = " WHERE ";
if(is_array($condition)){
$pair = array();
$size = count($condition);
$i = 0;
if($size > 1){
foreach($condition as $field => $val){
$i++;
if($size-1 == $i){
$query .= $val." = ? ".$clause. " ";
}else{
$query .= $val." = ? ";
}
}
}else{
foreach($condition as $field => $val){
$query .= $val." = ? ";
}
}
}else if(is_string($condition)){
$query .= $condition;
}else{
$query = "";
}
return $query;
}
The select function itself:
function crud_select($conn, $table, $args, $sort, $order, $clause){
$sql = create_select_query($table, array_keys($args),$sort, $order, $clause);
print_r($sql);
if($stmt = prepared_query($conn, $sql, array_values($args))){
return $stmt;
}else{
$errors [] = "Something weird happened...";
}
}
When I create the query, it seems to be OK but can't fetch the data. If I create an array with only one argument the query translates into:
SELECT * FROM `teste_table` WHERE id = ?
If I create with multiple parameters, it turns like this:
SELECT * FROM `teste_table` WHERE id = ? AND username = ?
So, how can I properly fetch the data from the select. This should be used for multiple purposes, so I could get more than one result, so the best way would be fetch data as array I guess.
I guess I'm close, but can't figure it out. Thanks
I told you to limit your select function to a simple primary key lookup. And now you opened a can of worms. As a result you are getting entangled implementation code and unreadable application code.
$table, $args, $sort, $order, $clause
What all these variables are for? How you're going to call this function - a list of gibberish SQL stubs in a random order instead of plain and simple SQL string? And how to designate a list of columns to select? How to use JOINS? SQL functions? Aliases? Why can't you just write a single SQL statement right away? You already have a function for selects, though without this barbaric error reporting code you added to it:
function prepared_query($mysqli, $sql, $params, $types = ""){
$types = $types ?: str_repeat("s", count($params));
$stmt = $mysqli->prepare($sql)) {
$stmt->bind_param($types, ...$params);
$stmt->execute();
return $stmt;
}
Just stick to it and it will serve you all right.
$sql = "SELECT * FROM `teste_table` WHERE id = ? AND username = ?";
$stmt = prepared_query($mysqli, $sql, [$id, $name]);
$row = $stmt->get_result()->fetch_assoc();
The only specific select function could be, again, a simple primary key lookup:
function crud_find($conn, $table, $id)
{
$table = escape_mysql_identifier($table);
$sql = "SELECT * FROM $table WHERE id=?";
$stmt = prepared_query($conn, $sql, [$id], "i");
return $stmt->get_result()->fetch_assoc();
}
And for the everything else just use a generic function with native SQL.
I am bit confused as when try the code below I receive the desired result.
include_once('config.class.php');
$db = Core::getInstance();
$whr = 'test#nannex.com';
$inv = $db->dbh->prepare("SELECT * FROM ruj_users WHERE email=:whr");
$inv->execute(array(":whr"=>$whr));
$row = $inv->fetch(PDO::FETCH_ASSOC);
echo $row['email'];
echo $row['full_name'];
However, when I run the following code it returns 1 not the desired result.
include_once('config.class.php');
$db = Core::getInstance();
$whr = 'test#nannex.com';
function fetchUser($whr){
$db = Core::getInstance();
$inv = $db->dbh->prepare("SELECT * FROM ruj_users WHERE :whr");
$inv->execute(array(':whr'=>$whr));
$res = $inv->fetch(PDO::FETCH_ASSOC);
return $res;
}
$row = fetchUser("email = '".$whr."' ");
echo $row['email'];
echo $row['full_name'];
This query:
SELECT * FROM ruj_users WHERE :whr
When expanded:
SELECT * FROM ruj_users WHERE 'email = \'test#nannex.com\''
The expression email = \'test#nannex.com\' will be evaluated by MySQL as a boolean and is always truthy, so it will return all rows in ruj_users.
If you want custom conditions, you can do something like this:
function fetchUser(array $conditions)
{
// ...
$sql = 'SELECT * FORM ruj_users WHERE';
$params = array();
foreach ($conditions as $column => $value) {
if (preg_match('/^[a-z]+$/', $column)) {
$sql .= "`$column` = ?";
$params[] = $value;
}
}
$inv = $db->dbh->prepare($sql);
$inv->execute(array_values($params));
// ...
}
fetchUser(array(
'email' => 'test#nannex.com',
'status' => 23,
));
You have an error in your query in the function:
$inv = $db->dbh->prepare("SELECT * FROM ruj_users WHERE :whr");
Should be:
$inv = $db->dbh->prepare("SELECT * FROM ruj_users WHERE email=:whr");
Edit: If you want to pass column names as well, you would have to add another variable to your function:
function fetchUser($column, $value) {
Note that only the value can be bound in a prepared statement, the column variable you would have to check against a white-list to avoid sql injection and hard-code in the query, like ... WHERE $column = :whr ...
I am passing a number of values to a function and then want to create a SQL query to search for these values in a database.
The input for this is drop down boxes which means that the input could be ALL or * which I want to create as a wildcard.
The problem is that you cannot do:
$result = mysql_query("SELECT * FROM table WHERE something1='$something1' AND something2='*'") or die(mysql_error());
I have made a start but cannot figure out the logic loop to make it work. This is what I have so far:
public function search($something1, $something2, $something3, $something4, $something5) {
//create query
$query = "SELECT * FROM users";
if ($something1== null and $something2== null and $something3== null and $something4== null and $something5== null) {
//search all users
break
} else {
//append where
$query = $query . " WHERE ";
if ($something1!= null) {
$query = $query . "something1='$something1'"
}
if ($something2!= null) {
$query = $query . "something2='$something2'"
}
if ($something3!= null) {
$query = $query . "something3='$something3'"
}
if ($something4!= null) {
$query = $query . "something4='$something4'"
}
if ($something5!= null) {
$query = $query . "something5='$something5'"
}
$uuid = uniqid('', true);
$result = mysql_query($query) or die(mysql_error());
}
The problem with this is that it only works in sequence. If someone enters for example something3 first then it wont add the AND in the correct place.
Any help greatly appreciated.
I would do something like this
criteria = null
if ($something1!= null) {
if($criteria != null)
{
$criteria = $criteria . " AND something1='$something1'"
}
else
{
$criteria = $criteria . " something1='$something1'"
}
}
... other criteria
$query = $query . $criteria
try with array.
function search($somethings){
$query = "SELECT * FROM users";
$filters = '';
if(is_array($somethings)){
$i = 0;
foreach($somethings as $key => $value){
$filters .= ($i > 0) ? " AND $key = '$value' " : " $key = '$value'";
$i++;
}
}
$uuid = uniqid('', true);
$query .= $filters;
$result = mysql_query($query) or die(mysql_error());
}
// demo
$som = array(
"something1" => "value1",
"something2" => "value2"
);
search( $som );
Here's an example of dynamically building a WHERE clause. I'm also showing using PDO and query parameters. You should stop using the deprecated mysql API and start using PDO.
public function search($something1, $something2, $something3, $something4, $something5)
{
$terms = array();
$values = array();
if (isset($something1)) {
$terms[] = "something1 = ?";
$values[] = $something1;
}
if (isset($something2)) {
$terms[] = "something2 = ?";
$values[] = $something2;
}
if (isset($something3)) {
$terms[] = "something3 = ?";
$values[] = $something3;
}
if (isset($something4)) {
$terms[] = "something4 = ?";
$values[] = $something4;
}
if (isset($something5)) {
$terms[] = "something5 = ?";
$values[] = $something5;
}
$query = "SELECT * FROM users ";
if ($terms) {
$query .= " WHERE " . join(" AND ", $terms);
}
if (defined('DEBUG') && DEBUG==1) {
print $query . "\n";
print_r($values);
exit();
}
$stmt = $pdo->prepare($query);
if ($stmt === false) { die(print_r($pdo->errorInfo(), true)); }
$status = $stmt->execute($values);
if ($status === false) { die(print_r($stmt->errorInfo(), true)); }
}
I've tested the above and it works. If I pass any non-null value for any of the five function arguments, it creates a WHERE clause for only the terms that are non-null.
Test with:
define('DEBUG', 1);
search('one', 'two', null, null, 'five');
Output of this test is:
SELECT * FROM users WHERE something1 = ? AND something2 = ? AND something5 = ?
Array
(
[0] => one
[1] => two
[2] => five
)
If you need this to be more dynamic, pass an array to the function instead of individual arguments.
I have the following code:
$sql = "SELECT name, address, city FROM tableA, tableB WHERE tableA.id = tableB.id";
if (isset($price) ) {
$sql = $sql . ' AND price = :price ';
}
if (isset($sqft) ) {
$sql = $sql . ' AND sqft >= :sqft ';
}
if (isset($bedrooms) ) {
$sql = $sql . ' AND bedrooms >= :bedrooms ';
}
$stmt = $dbh->prepare($sql);
if (isset($price) ) {
$stmt->bindParam(':price', $price);
}
if (isset($sqft) ) {
$stmt->bindParam(':price', $price);
}
if (isset($bedrooms) ) {
$stmt->bindParam(':bedrooms', $bedrooms);
}
$stmt->execute();
$result_set = $stmt->fetchAll(PDO::FETCH_ASSOC);
What I notice is the redundant multiple IF statements I have.
Question: is there any way to clean up my code so that I don't have these multiple IF statements for prepared statements?
This is very similar to a question a user asked me recently the forum for my book SQL Antipatterns. I gave him an answer similar to this:
$sql = "SELECT name, address, city FROM tableA JOIN tableB ON tableA.id = tableB.id";
$params = array();
$where = array();
if (isset($price) ) {
$where[] = '(price = :price)';
$params[':price'] = $price;
}
if (isset($sqft) ) {
$where[] = '(sqft >= :sqft)';
$params[':sqft'] = $sqft;
}
if (isset($bedrooms) ) {
$where[] = '(bedrooms >= :bedrooms)';
$params[':bedrooms'] = $bedrooms;
}
if ($where) {
$sql .= ' WHERE ' . implode(' AND ', $where);
}
$stmt = $dbh->prepare($sql);
$stmt->execute($params);
$result_set = $stmt->fetchAll(PDO::FETCH_ASSOC);
Instead of if else just use PHP ternary operator
if (isset($_POST['statusID']))
{
$statusID = $_POST['statusID'];
}
else
{
$statusID = 1;
}
instead of that you can do:
$statusID = (isset($_POST['statusID'])) ? $_POST['statusID'] : 1;
The format of the ternary operator is: $variable = condition ? if true : if false
The beauty of it is that you will shorten your if/else statements down to one line and if compiler ever gives you errors, you can always go back to that line instead of 3 lines.
I have a similar problem with delete command too..
function deleteUsers($userID) {
foreach($userID as $key => $val)
{
$query = "DELETE FROM members WHERE member_id = '$val'";
$result = mysql_query($query);
}
//$query = "DELETE FROM members WHERE member_id = $userID";
//$result = mysql_query($query);
if($result)
{
return 'yes';
}
}
its not performing multi delete.... the $userID contains array. Its not going inside the Query.
When using multiple IDs use variable IN (1,2,3) format rather than simple equality. Also if you have more than one ID maybe the variable should be called $userIDs?
if(count($userID) > 0) {
$query = 'DELETE FROM members WHERE member_id IN ('. implode(',', $userID) .')';
}
Without foreach:
function deleteUsers($userID) {
if (count($userID)) {
$query = "DELETE FROM `members` WHERE `member_id` IN (".implode(",", array_values($userID)).");";
if (mysql_query($query)) { return true; }
}
return false;
}
This will make the function to understand array as well as single integer:
function deleteUsers($u) {
$condition = is_array($u)
? "member_id IN (" . implode(',', $u) . ")"
: "member_id = " . (int)$u;
$res = mysql_query("DELETE FROM `members` WHERE $condition");
return $res ? true : false;
}
Remember that your parameters are not properly escaped and cannot be trusted. To learn more on escaping SQL and preventing injection attacks read about Prepared Statements.
Please, for the love of the internet, don't built an SQL query yourself. Use PDO.