I'm trying to create a search for my site and I'm having lots of trouble doing it. In my movies database I have two tables: movieinfo and movie_genres. Under movieinfo, there is Movie_Name, actor1, actor2, actor3, actor4. Under the movie_genres table, there is Genre_Id. (There are more columns in each of the tables, but I only want to search those columns.)
My current code is:
<?php
if ($_GET) {
$search = $_GET['search'];
$connect = mysql_connect("localhost","root","spencer");
if($connect) {
mysql_select_db("movies", $connect);
$query = "SELECT Movie_Name, actor1, actor1, actor1, actor1, Genre_Id FROM movieinfo, movie_genres WHERE * LIKE '%:search%' OR actor1 LIKE '%:search%' OR actor2 LIKE '%:search%' OR actor3 LIKE '%:search%' OR actor4 LIKE '%:search%' OR Genre_Id = ? ";
$results = mysql_query($query);
while($row = mysql_fetch_array($results)) {
echo $row['Poster'] . "<br/>" . $row['Movie_Name'];
}
} else {
die(mysql_error());
}
}
?>
Everything in movieinfo I'm searching for is VARCHAR, and movie_genres is an INT (incase that makes much of a difference). I think I'm close to what the code should be, but I don't know.
As of right now, I get the following error while trying to search:
Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in C:\xampp\htdocs\movies\get_search.php on line 12
New code:
<?php
// Connection data (server_address, database, name, poassword)
$hostdb = 'localhost';
$namedb = 'movies';
$userdb = 'root';
$passdb = 'spencer';
try {
// Connect and create the PDO object
$conn = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb);
$conn->exec("SET CHARACTER SET utf8"); // Sets encoding UTF-8
}
catch (PDOException $e) {
$v_errormsg = $e->getMessage();
$error_str = <<<END_HTML
<h2> Error connecting to database: Message: $v_errormsg <h2>
END_HTML;
echo $error_str;
die;
}
$sql = <<<END_SQL
SELECT Movie_Name FROM movieinfo WHERE Movie_Name LIKE '%":search"%' ";
END_SQL;
try {
$sth = $conn->prepare($sql);
$sth->execute();
}
catch (PDOException $e) {
$v_errormsg = $e->getMessage();
$error_str = <<<END_HTML
<h2> Error selecting data: Message: $v_errormsg <h2>
END_HTML;
echo $error_str;
die;
}
$num_rows = 0;
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
$Movie_Name = $row['Movie_Name'];
}
echo $row['Movie_Name'];
?>
You can't use part of a string as a placeholder; placeholders can only take the place of a single entire value. Use LIKE :search and bind '%' . $search . '%' as the value.
You aren't binding any values. :)
You are getting an invalid query because you're using bind paramter syntax from PDO
start with something very simple like
$search= mysql_escape_string($search);
$query = "SELECT Movie_Name FROM movie_info WHERE name LIKE '%".$search."%';
Once you get that working, move on to the more complex logic...
Better yet, use PDO to do the query:
<?php
$stmt = $db->prepare("SELECT * FROM table WHERE id=:id AND name=:name");
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
$stmt->bindValue(':name', $name, PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
example from: http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers
Related
I have a query and works:
$sql2 = "SELECT id FROM table WHERE '2022-06-06' BETWEEN date(se_from) AND date(se_to)";
But when the date is dynamic the query fails:
$pick_date = '2022-06-06';
$sql2 = "SELECT id FROM tblseasons WHERE $pick_date BETWEEN date(se_from) AND date(se_to)";
Can't understand, can anyone explain.
Thanks
Your query lacks parentheses in the date (so it fails to do what you want as the query will be invalid)
For security, please use parameterized prepared statement to avoid SQL injection attacks instead
For mysqli, it will be:
$conn = mysqli_connect("localhost", "user", "dbpass", "dbname1");
$pick_date = '2022-06-06';
$sql2 = "SELECT id FROM tblseasons WHERE ? BETWEEN date(se_from) AND date(se_to)";
$stmt = $conn->prepare($sql2);
$stmt->bind_param("s", $pick_date);
$stmt->execute();
$result = $stmt->get_result(); // get the mysqli result
while ($row = $result->fetch_assoc()) {
echo $row['id'] . "<br>"; // if you want to see the result;
}
For PDO, it will be
$dbh = new PDO('mysql:host=localhost;dbname=dbname1', "user", "dbpass");
$pick_date = '2022-06-06';
$string1 = "SELECT id FROM tblseasons WHERE :pick_date BETWEEN date(se_from) AND date(se_to)";
$stmt = $dbh->prepare($string1, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$stmt->execute([':pick_date' => $pick_date]);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo $row["id"] . "<br>"; // if you want to see the result;
}
I've established a database full of movies which is connected to a HTML form of which the information is ported with PHP POST (Acts as a movie database).
When the user enters a search term (Either title, genre, year or classification) the PHP script search.php is handed the information.
This goes fine, however, i also have a column in my DB which is titled times_searched which has a default value of zero.
I feel like one of the big problems is i've just been staring at this file for too long and something simple is not apparent to me right now.
I'm very new to PHP and WebDev in general.
I have tried issuing a second statement to execute inside the foreach loop of the TableRow class and have tried different syntaxes and attempting to bind previous statements to new statements.
class TableRows extends RecursiveIteratorIterator
{
function __construct($it)
{
parent::__construct($it, self::LEAVES_ONLY);
}
function current()
{
return "<td style='width:150px;border:1px solid black;'>" .
parent::current()."</td>";
}
function beginChildren()
{
echo "<tr>";
}
function endChildren()
{
echo "</tr>" . "\n";
}
}
function printAssocArray($stmt)
{
foreach (new TableRows(new RecursiveArrayIterator($stmt->fetchAll()))
as $k=>$v) {
echo $v;
}
}
require 'Templates/header.php';
//DB variables
$serverName = "localhost";
$userName = "root";
$password = "";
//Post variables
$title = ($_POST['title']);
$year = ($_POST['year']);
$genre = ($_POST['genre']);
$rating = ($_POST['rating']);
if (isset($_POST['submit'])) {
try {
//Create PDO object using DB variables
$conn = new PDO(
"mysql:host=$serverName;dbname=project_db", $userName, $password
);
//Set PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "<h3 class='center'>Connection Successful!</h3>";
if (!empty($_POST['title']) && empty($_POST['genre'])
&& empty($_POST['rating']) && empty($_POST['year'])
) {
$stmt = $conn->prepare(
"UPDATE movies SET
times_searched = times_searched + 1 WHERE id = :id;
IN (SELECT * FROM movies WHERE title LIKE '%$title%'"
);
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->bindValue(':id', $result['id']);
$stmt->execute();
//Use function call to print information to table using TableRows
printAssocArray($stmt);
}elseif (!empty($_POST['genre']) && empty($_POST['rating'])
&& empty($_POST['year']) && empty($_POST['title'])
) {
$stmt = $conn->prepare(
"SELECT * FROM movies WHERE genre LIKE '%$genre%'"
);
$stmt->execute();
//Collect Result in associative array
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
//Use function call to print information to table using TableRows
printAssocArray($stmt);
}
//New Block
if (!empty($_POST['title']) && empty($_POST['genre'])
&& empty($_POST['rating']) && empty($_POST['year'])
) {
$updateQuery = "UPDATE movies SET times_searched = times_searched + 1
WHERE id IN (SELECT id FROM movies WHERE title LIKE :title)";
$stmt = $conn->prepare($updateQuery);
$stmt->bindValue(':title', "%{$title}%");
$stmt->execute();
$outputQuery = "SELECT * FROM movies WHERE title LIKE :title";
$stmt2 = $conn->prepare($outputQuery);
$stmt2->bindValue(':title', "%{$title}%");
$data = $stmt2->fetchAll(PDO::FETCH_ASSOC);
foreach ($data as $row) {
foreach ($row as $v) {
echo $v, " ";
}
echo "<br>",\n;
}
The aim is to try and return the requested query from the database then increment the times_searched column before printing it using the TableRow Class, this should happen each time the query is run (if the page is refreshed the times_searched column should increment)
This is being used for completion of a homework project, and security is not nessacarily a factor (though use of PDO was requested).
Your query should either use WHERE id = :id (single movie item) or WHERE id IN (SELECT id FROM movies WHERE title LIKE '%$title%') (multiple movie items), not both, not separated by a ;.
I assume you want to use the latter (update multiple movie items), change
$stmt = $conn->prepare(
"UPDATE movies SET
times_searched = times_searched + 1 WHERE id = :id;
IN (SELECT * FROM movies WHERE title LIKE '%$title%'"
);
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->bindValue(':id', $result['id']);
$stmt->execute();
to
$stmt = $conn->prepare("UPDATE movies SET times_searched = times_searched + 1 WHERE id IN (SELECT id FROM movies WHERE title LIKE :title)");
$stmt->bindValue(':title',"%{$title}%");
$stmt->execute();
For the // New Block part:
Replace
$outputQuery = "SELECT * FROM movies WHERE title LIKE '%title%'";
$stmt2 = $conn->prepare($outputQuery);
$stmt2->bindValue('title', $title);
with
$outputQuery = "SELECT * FROM movies WHERE title LIKE :title";
$stmt2 = $conn->prepare($outputQuery);
$stmt2->bindValue(':title', "%{$title}%");
I am trying to make SQL in php to return all the entries that matches a keyword that is entered by the user (from search bar).
I want to return all the entries that their name "partial" matches with the keyword.
I want at least to match the keyword, if an entry name in database before has space and after maybe another letter/space.
For example I have three entries with names "Milk", "Semi skimmed Milk" and "Full Milk 2". If the keyword is "Milk" or "milk" or "MiLK", I want to get all these three entries.
The only case I am thinking it might be the problem is case sensitive.
I tried with a keyword that exists exactly in database, but my app (on android) stops .
Based on user3783243 answer.
PHP FILE
<?php
$servername = "";
$username = "";
$password = "";
$dbname = "";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT name FROM items WHERE name LIKE CONCAT ('%', ?, '%')";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $keyword);
$res = $stmt->get_result();
while($row = $res->fetch_assoc()) {
echo $row["name"] . ",";
}
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo $row["name"] . ",";
}
} else {
echo "0";
}
$conn->close();
?>
Your query should be:
$sql = "SELECT * FROM items WHERE name LIKE CONCAT ('%', ?, '%')";
and then $keyword should be bound with whatever syntax the driver you are using supports.
As is your query would have been:
SELECT * FROM items WHERE name LIKE CONCAT ('%', Milk, '%')
and you wanted Milk to be a string so it needed to be quoted. As is mysql would have thought that was a column.
Alternatively you could do:
$keyword = '%' . $_POST['keyword'] . '%';
$sql = "SELECT * FROM items WHERE name LIKE CONCAT ?";
that is the same and still requires the binding though.
The binding also takes away the SQL injection. See How can I prevent SQL injection in PHP? and/or https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#Defense_Option_1:_Prepared_Statements_.28with_Parameterized_Queries.29
Per update.. replace:
$keyword =$_POST['keyword'];
$sql = "SELECT * FROM items WHERE name LIKE '%$keyword%)";
$result = $conn->query($sql);
with:
$sql = "SELECT name FROM items WHERE name LIKE CONCAT ('%', ?, '%')";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $keyword);
$stmt->execute();
$res = $stmt->get_result();
if(empty($conn->errno) && !empty($res)) {
while($row = $res->fetch_assoc()) {
echo $row["name"] . ",";
}
} else {
echo '0';
//print_r($conn->errno);
}
$conn->close();
...
also remove
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo $row["name"] . ",";
}
} else {
echo "0";
}
$conn->close();
In this case you can convert the input in search bar to either upper or lower case by default then apply query in db like
For Upper case:
$keyword =strtoupper($_POST['keyword']);
$sql = "SELECT * FROM items WHERE upper(name) LIKE '%$keyword%)";
Or for lower case:
$keyword =strtolower($_POST['keyword']);
$sql = "SELECT * FROM items WHERE lower(name) LIKE '%$keyword%)";
I just started playing around with PDO and I am trying to create a function that will display all the data for a given table name. After reading a few posts here I found a solution that I can get working (shown below with a hard-coded select statement). However, I can't get my execute statements to work when I bind my field names (I get an exception similar to: Undefined index: person_id). I should mention my class extends PDO:
/*********************************************************************
*Function showTable
*Purpose Display all information for a given table.
*Params $sTable -> Table name
********************************************************************/
public function showTable($sTable)
{
$result;
try
{
if(isset($sTable))
{
//create a result in a table format
$result = "<table>";
//$stmt = $this->prepare('DESCRIBE :sTable');
$stmt = $this->prepare('DESCRIBE ' . $sTable);
//$stmt->bindParam(':sTable', $sTable);
$stmt->execute();
//array version of the column names
$aCols = $stmt->fetchAll(PDO::FETCH_COLUMN);
//string version of the column names
$sCols = implode (", ", $aCols);
//$stmt = $this->prepare('SELECT :fields FROM :sTable');
//$stmt = $this->prepare('SELECT :fields FROM person');
$stmt = $this->prepare('SELECT person_id, first_name, last_name FROM person');
//$stmt->execute(array(':fields'=>$sCols, 'stable'=>$sTable));
//$stmt->execute(array(':fields'=>$sCols));
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
var_dump($row);
$result = $result . "<tr>";
foreach($aCols as $col)
{
//var_dump($row);
$result = $result . " <td>" . $row[$col]. "</td>";
}
$result = $result . "</tr>";
}
$result = $result . "</table>";
}
return $result;
}
catch(PDOException $e)
{
if($this->bDebug)
{
echo $e->getMessage();
}
}
}
Like I said the hard coded select string works but when i comment out the hard coded and uncomment the execute with a bind it throws exceptions.
You cannot insert identifiers or keywords this way.
PDOStatement::execute() will put the value in escaped form inside single quotes. Your query would look like:
SELECT 'col1, col2' FROM person
What is invalid MySQL syntax.
A valid example:
$stmt = $this->prepare('SELECT col FROM person WHERE name = :name');
$stmt->execute(array(':name' => $name));
It works, because it's a value you insert here; and not an keyword or identifier.
I want to execute a query that i saved in my database like this:
ID | NAME | QUERY
1 | show_names | "SELECT names.first, names.last FROM names;"
2 | show_5_cities | "SELECT cities.city FROM city WHERE id = 4;"
Is this possible ?
I am kinda noob in php so plz explain if it is possible.
If I understand you correctly, you have your queries saved in the database in a table and you want to execute those.
Break the problem down: you have two tasks to do:
Query the database for the query you want to run.
Execute that query.
It's a bit meta, but meh :)
WARNING: the mysql_ functions in PHP are deprecated and can be dangerous in the wrong hands.
<?php
if (!$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')) {
die('Could not connect to mysql');
}
if (!mysql_select_db('mysql_dbname', $link)) {
die('Could not select database');
}
$name = "show_5_cities"; // or get the name from somewhere, e.g. $_GET.
$name = mysql_real_escape_string($name); // sanitize, this is important!
$sql = "SELECT `query` FROM `queries` WHERE `name` = '$name'"; // I should be using parameters here...
$result = mysql_query($sql, $link);
if (!$result) {
die("DB Error, could not query the database\n" . mysql_error(););
}
$query2 = mysql_fetch_array($result);
// Improving the code here is an exercise for the reader.
$result = mysql_query($query2[0]);
?>
if you did create a stored procedure/function you can simply use:
mysql_query("Call procedure_name(#params)")
Thats will work. reference here: http://php.net/manual/en/mysqli.quickstart.stored-procedures.php
Querying the table to get the query, then executing that query and looping through the results and outputting the fields
<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno())
{
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$RequiredQuery = intval($_REQUEST['RequiredQuery']);
$sql = "SELECT `QUERY` FROM QueryTable WHERE ID = $RequiredQuery";
$result = mysqli_query($link, $sql);
if ($row = mysqli_fetch_assoc($result))
{
$sql = "SELECT `QUERY` FROM QueryTable WHERE ID = $RequiredQuery";
$result = mysqli_query($link, $row['QUERY']);
while ($row2 = mysqli_fetch_assoc($result))
{
foreach($row2 AS $aField=>$aValue)
{
echo "$aField \t $aValue \r\n";
}
}
}
?>
just open the Table and get the individual query in a variable like
$data = mysql_query('SELECT * FROM <the Table that contains your Queries>');
while(($row = mysql_fetch_row($data)) != NULL)
{
$query = $row['Query'];
mysql_query($query); // The Query from the Table will be Executed Individually in a loop
}
if you want to execute a single query from the table, you have to select the query using WHERE Clause.