I have a SQL statement where I want the WHERE part to be dynamically filled by the calling function. The function that calls the statement should be able to pass one or more parameters with 'OR'. Unfortunately, the statement always takes only the first entry.
$category = 'cat1' OR 'cat2' OR 'cat3';
$result = getEntries($category, $mysqli);
function getEntries($category, $mysqli){
$queryData = $mysqli->prepare("SELECT * FROM items WHERE category = ?");
$queryData->bind_param("s", $category);
$queryData->execute();
$queryData = $queryData->get_result();
return $queryData;
}
I only get results for "cat1"
Thanks for your help
You are using OR operator to assign a variable, which will assign one value at a time, if you want the number of categories dynamically then you can modify your code like below:
$categories = ['cat1','cat2','cat3'];
$result = getEntries($categories, $mysqli);
function getEntries($categories, $mysqli){
$plcs = implode(',',array_fill(0,count($categories)-1, "?");
$queryData = $mysqli->prepare("SELECT * FROM items WHERE category IN ({$plcs})");
$queryData->bind_param(str_repeat("s", count($categories)), ...$categories);
$queryData->execute();
return $queryData->get_result();
}
wrong assignment .
$category = 'cat1' OR 'cat2' OR 'cat3';
correct it . See the basics of bind param from below :
https://www.php.net/manual/en/mysqli-stmt.bind-param.php
And multiple where statment can be like this :
SELECT * FROM items WHERE category in ("cat1","cat2","cat3")
also you can use following when your database has extra space or want to match anything containing cat1,cat2,cat3:
SELECT * FROM items WHERE category like '%cat1%' or category like '%cat2%' or
category like '%cat3%'
Related
This question already has answers here:
How can I use PDO to fetch a results array in PHP?
(2 answers)
Closed last month.
I'm fairly new with PHP and with MySQL/Wampserver/MVC model, as i'm still learning it. In a project i'm working on, i have a database containing multiple tables ( users, posts, commentary ). I've worked out how to 1)register a new post inside the db upon submitting a form, and on an homepage, fetch all the posts to show them in a list. Such has been done through the following code :
public function getAllPosts()
{
$query = "SELECT * FROM posts ORDER BY timestamp(date) desc LIMIT 5";
$request = $this->db->prepare($query);
$request->execute();
$allPost = $request->fetchAll(PDO::FETCH_ASSOC);
var_dump($allPost);
return $allPost ? $allPost : [];
}
$allPost here is returned as an array, containing multiple infos
Since this array contains the IDs of every post, my idea to select a specific ID from a specific post is to fetch the ID existing in the array generated to make the list of post, and pass it to the address with the POST method.
Is this a convoluted thing to do ? If so, what would you suggest i do instead ?
The things i tried so far :
Create a new public function that grabs the ID with a new query from the database ( "SELECT id FROM tablename WHERE id=?") but this did not work, and simply returned " boolean false " on var_dump
public function getOnePostById()
{
$query = "SELECT id FROM posts WHERE id=?";
$request = $this->db->prepare($query);
$request->execute();
$singlePost = $request->fetch(PDO::FETCH_ASSOC);
var_dump($singlePost);
}
I then tried to pass to getOnePostById the resulting array from the previous function while this seems to be accepted by my code, in my controller afterwards, the array $allPost was flagged as an undefined variable
You have to provide a value for a placeholder in the query, either by using bindParam or bindValue method of PDOStatement or adding it as array parameter to execute()
public function getAllPosts(): array
{
$query = "SELECT * FROM posts ORDER BY timestamp(date) desc LIMIT 5";
$request = $this->db->query($query);
return $request->fetchAll(PDO::FETCH_ASSOC);
}
// if your Post ID is not a number, use string $id
public function getOnePostById(int $id): ?array
{
$query = "SELECT * FROM posts WHERE id = ?";
$request = $this->db->prepare($query);
$request->execute([$id]);
return $request->fetch(PDO::FETCH_ASSOC);
}
// Here you can just check post existence by given id
// if your Post ID is not a number, use string $id
public function isPostExists(int $id): bool
{
$query = "SELECT 1 AS exist FROM posts WHERE id = :id";
$request = $this->db->prepare($query);
// if your Post ID is not a number, use PDO::PARAM_STR
$request->bindParam('id', $id, PDO::PARAM_INT);
$request->execute();
// FETCH_OBJ example
return (bool)$request->fetch(PDO::FETCH_OBJ);
}
P.S. FETCH_ASSOC is bad practice (because it's just an array, it can be a list of entries, or it can be a single entry). PDO::FETCH_OBJ should be preferred.
See more about PDO fetch modes and how to set default fetch mode (for entire PDO instance, not just PDOStatement) and many other settings here.
UPD:
And also $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); is good practice, your PDO instance will throw exceptions instead of silent failures.
See difference between bindParam and bindValue - here
$output = QuerySelect($sqlCheckSameTeamLead, $selectBindings);
function QuerySelect($query, $bindings = NULL){
global $connPDO;
$statement = $connPDO->prepare($query); //prepare statement
$statement->execute($bindings); //execute Statment
return $statement->fetchAll(PDO::FETCH_ASSOC); //return result in associative array
}
I am looking for a way to get $output second row and specific column but without loop. I can loop through $outputbut i want to avoid it.
My suggestion is that you dothat via your query
Example:
SELECT * FROM table_name LIMIT 1, 1
Gets only the second row, then you can use SELECT clause to get the desired columns.
In a php page, I have an array, similar to this:
$category = array(16, 22, 23);
Then I am doing a database query with a prepared statement. I would like to get all rows where the field category contains one of the values from that $category array and where price is lower than a value stored in the variable $price.
Among others I read the answers to this question and tried to use find_in_set() as described there (and at a lot of other places), but somehow I can't make it work within the prepared statement. I tried this:
/* database connection "$db" is established beforehand and works */
if($ps = $db->prepare("
SELECT id, product, category, price
FROM products
WHERE price <= ? and find_in_set(?, category)
ORDER BY id") {
$ps->bind_param("ds", $price, $category);
$ps->execute();
$ps->bind_result($id, $name, $cat, $pr);
while($ps->fetch()) {
/* ... echo the results ..... */
}
$ps->free_result();
$ps->close();
}
But I get an empty result.
If I try to use "dd" or "di" instead of "ds" in the bind_param() line, I do get results, but the wrong ones - I get all rows with category 1.
I also tried to use category IN ? instead of find_in_set(?, category), but that won't work either.
What can I do to make that work? Any help appreciated!
Two issues:
The list should be passed as second argument to find_in_set, so it should be:
find_in_set(category, ?)
That argument should be of type string (comma separated values). So first convert your array to such a string with implode:
$csv = implode(",", $category);
Code:
if($ps = $db->prepare("
SELECT id, product, category, price
FROM products
WHERE price <= ? and find_in_set(category, ?)
ORDER BY id") {
$csv = implode(",", $category);
$ps->bind_param("ds", $price, $csv);
$ps->execute();
$ps->bind_result($id, $name, $cat, $pr);
while($ps->fetch()) {
/* ... echo the results ..... */
}
$ps->free_result();
$ps->close();
}
If you want to find values where $category belongs to a certain set try using IN. Just a note you cannot pass an array into a string like you have above.
Also don't forget to convert your array to a CSV string using implode
$category = array(16, 22, 23);
$cat_str = implode(",",$category); //16,22,23
$ps = $db->prepare("
SELECT id, product, category, price
FROM products
WHERE price <= ? and category IN (?)
ORDER BY id") {
$ps->bind_param("ds", $price, $cat_str);
if i tried the same case , then i would probably have done it like this
SELECT id, product, category, price
FROM products
WHERE category = '16' || category = '22' || category = '23' and price < $price`
i am assuming your $category array variable is fixed , it's not dynamically appending value .
I answered only your query part . i'd hope you have php coding convention idea rather than putting the entire statement in the if statement .
if still has anything to ask about , please go ahead
I would like to get the id of an item in the database, set it to a variable, and use it. I'm quite new to all this coding stuff. I'm basing this on.
http://jameshamilton.eu/content/simple-php-shopping-cart-tutorial?PHPSESSID=99d373741727e3010a32319f1ebed001
cart.php?action=add&pdin=fbs
$product = $_GET[pdin];
I can't use an integer for 'pdin' so, id like to use its corresponding id which is an integer and plug it into this line of code which only takes integers?
$sql = sprintf("SELECT * FROM products WHERE pdin = %d;", $product);
so in i would take $product = 'pdin' find it's id $id = 'id' and plug it in to the above code
$sql = sprintf("SELECT * FROM products WHERE id = %d;", $id);
I tried reading up on this sql FROM SELECT WHERE... confused me some
I'd use a prepared statement which would also make yourself a bit safer from SQL injection. What database interface are you using from php to mysql?
Here's one option:
$product = $_GET['pdin'];
$stmt = $db->Prepare("select * from products where pdin = ?");
$res = $db->GetAssoc($stmt,$product);
btw,
if you acces array items via key, always use quotations (' or ") otherwise PHP (unnecessary) first check, if key is constant
Ok, I figured it out. I'm sorry i didn't explain it all that well last night. I have a limited brain battery per day, and last night it was depleted.
What i wanted was quite simple. I wanted to find an items associated id in the database.
$query = "SELECT * FROM products WHERE pdin = '$product'";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_assoc($result)) {
$productID = $row['id'];
}
Now that parts done and returns the correct id. And the 'item exists' function fires correctly.
//function to check if a product exists
function productExists($productID) {
//use sprintf to make sure that $productID is inserted into the query as a number - to prevent SQL injection
$sql = sprintf("SELECT * FROM products WHERE id = %d;", $productID);
return mysql_num_rows(mysql_query($sql)) > 0;
}
So, Mark and Michal Hatak; When you where talking about using quotations on keys, does that mean...
$sql = sprintf("SELECT * FROM products WHERE 'id' = %d;", $productID);
putting quotations around things like 'id'? And it's for security?
Forgive me, I'm a new graphic designer and not adept at code.
I am looking for idea to change radio to checkbox and make SQL SELECT with it:
Now The user chooses category by form radio (one category) code:
$zapytanie = $pdo->prepare('SELECT * FROM pytania_new WHERE Kategoria = :kategoria');
and the script show all questions with one category which we chose.
Now I would like to have choosing a few category, so I changed my current code to show checkbox form and save chosen category to array, but now I don't know how to do SQL which show me questions with a few category
$zapytanie = $pdo->prepare('SELECT * FROM pytania_new WHERE Kategoria = :kategoria AND :kategoria2');
this doesn't want to work.
and the next problem is how to check how much category SQL should download from database.
I hope that you help me with it :)
AND operator requires column to be mentioned, not value
So in your case Kategoria = :kategoria AND Kategoria2 = :kategoria2
But we don't have your structure, maybe you don't have second column, so you need to recieve 2 rows as a result? Then use OR operator:
Kategoria = :kategoria OR Kategoria = :kategoria2
You can do this with a simple for loop.
$categories = array("first","second");
$query = "";
$delimiter = "";
foreach($categories as $category) {
$query .= $delimiter . "kategoria = $category";
$delimiter = " OR "; //Dont really know how your sql looks but this makes more sense. Otherwise change to AND if a row can have multiple categories
}
$sql = "SELECT * FROM pytania_new WHERE $query";
OK, so on the first we have to create string with all categories like this:
$kategorie = join(',',$kategoria);
After that there is simple SQL which can find a few category in base
$zapytanie = $pdo->prepare("SELECT * FROM pytania_new WHERE Kategoria IN ($kategories)");
and it is all :)