php mysqli prepared statement - php

Hey, I have a quick one. Is there any way to include a variable into a prepared query? example:
$sql = "SELECT id, title, author, LEFT(description, 40) AS excerpt,
image_small, image_med, date
FROM posts
ORDER BY id DESC
LIMIT $start, $postsPerPage";
$result = $connect->prepare($sql) or die ('error');
$result->execute();
$result->bind_result($id, $title, $author, $excerpt, $image_small, $image_med, $date);
Thanks!

you want the following:
$start = 1; $postsPerPage = 1;
$sql = "SELECT id, title, author, LEFT(description, 40) AS excerpt,
image_small, image_med, date
FROM posts
ORDER BY id DESC
LIMIT ?, ?";
$stmt = $connect->prepare($sql) or die ('error');
$stmt->bind_param('ii', $start, $postsPerPage);
$stmt->execute();
$stmt->bind_result($id, $title, $author, $excerpt, $image_small, $image_med, $date);
while($stmt->fetch()) {
printf('<h1>%s</h1><p>%s <small> by %s on %s</small></p>',
htmlspecialchars($title),
htmlspecialchars($excerpt),
htmlspecialchars($author),
htmlspecialchars($date)
);
}
this binds both question marks to integer (i) values of $start and $postsPerPage. do NOT use variables directly in prepared statements, because that would defeat the whole purpose of prepared statements (apart from eliminating parsing time)

Use question marks as placeholders in the SQL where you want the value of the variable to be.
Use mysqli_stmt::bind_param to bind values to the placeholders.

If I'm not mistaken you have to use bindParam and replace the variables in your query with a question mark
$sql = "SELECT id, title, author, LEFT(description, 40) AS excerpt,
image_small, image_med, date
FROM posts
ORDER BY id DESC
LIMIT ?, ?";
$result = $connect->prepare($sql) or die ('error');
$result->bindParam(1, $start);
$result->bindParam(2, $postsPerPage);
you can find more examples at http://php.net/manual/en/pdo.prepared-statements.php

Related

Why this SQL query return false when i try to bind values (even prepare statement)?

I tried to solve it with PDO and mysqli prepared statements but it still return false. So something is probably wrong with sql statement only, but i don't know what exacly.
$query = $db->prepare('SELECT * FROM bricks WHERE "text" LIKE CONCAT("%", :phrase, "%") AND tags LIKE CONCAT("%", :tag, "%") ORDER BY hearts DESC LIMIT {$start},{$pagesOnSite}');
$query->bindValue(':phrase', $phrase, PDO::PARAM_STR);
$query->bindValue(':tag', $tag, PDO::PARAM_STR);
$query->execute();
I also tried it this way:
$sql='SELECT * FROM bricks WHERE "text" LIKE CONCAT("%", ?, "%") AND tags LIKE CONCAT("%", ?, "%") ORDER BY hearts DESC LIMIT {$start},{$pagesOnSite}';
$stmt = $db->prepare($sql);
$stmt->bind_param("ss", $phrase, $tag);
$stmt->execute();
If you want to bind some text literal surrounded by wildcards, then you should build that entire string value in your PHP code. Then, bind it to your statement.
$sql = "SELECT * FROM bricks ";
$sql .= "WHERE text LIKE :phrase AND tags LIKE :tag ";
$sql .= "ORDER BY hearts DESC LIMIT {$start}, {$pagesOnSite}";
$query = $db->prepare($sql);
$query->bindValue(':phrase', '%'.$phrase.'%', PDO::PARAM_STR);
$query->bindValue(':tag', '%'.$tag.'%', PDO::PARAM_STR);
$query->execute();

Prevent lnjection on large sql select statement using like and %

I have a large sql query which I am trying to prevent injection on.
Because the query uses like and '%' on the variables I do not know how to format it and my usual method of
$sql = "INSERT into UsedBook ( userId, bookId, price, description ) VALUES
(?,?,?,?)";
if($stmt = mysqli_prepare($conn, $sql)){
mysqli_stmt_bind_param($stmt, "iiis", $userId, $bookId, $price,
$description);
mysqli_stmt_execute($stmt);
}
Doesn't fit the format.
Here is my large query. Look near the bottom for the like statements with the variables.
$sql = "SELECT DISTINCT Offering.offeringId, UsedBook.saleId,
UsedBook.bookId, UsedBook.price,
UsedBook.timeStamp, Book.bookName, Classes.classNumber, Instructor.name,
Classes.departmentName, Offering.section, Users.email, UsedBook.description
FROM UsedBook, Book, Classes, Offering, Instructor, RequiredBook, Users
WHERE UsedBook.bookId = Book.bookId
and Classes.classId = RequiredBook.classId and Book.bookId =
RequiredBook.bookId
and Classes.classId = Offering.classId and Offering.instructorId =
Instructor.instructorId
and Offering.semesterId = $semester and UsedBook.userId = Users.userId and
UsedBook.userId != $userId
and Classes.departmentName like '$departmentName%' and Classes.classNumber
like '$classNumber%'
and Book.bookName like '$bookName%' and Offering.section like '$section%'";
You can still use a prepared statement, you just need to incorporate the % into the bound parameter e.g.
$sql = "SELECT * FROM UsedBook WHERE bookName LIKE ?";
$param = "$bookName%";
if($stmt = mysqli_prepare($conn, $sql)){
mysqli_stmt_bind_param($stmt, "s", $param);
mysqli_stmt_execute($stmt);
}

Can't add LIKE to my SQL query

include("config.php");
$page_number = filter_var($_POST["page"], FILTER_SANITIZE_NUMBER_INT, FILTER_FLAG_STRIP_HIGH);
if(!is_numeric($page_number)){
header('HTTP/1.1 500 Invalid page number!');
exit();
}
session_start();
$position = (($page_number-1) * $item_per_page);
if(!empty($_SESSION['type'])){
$typesql = $_SESSION['type'];
$results = $mysqli->prepare("SELECT name, location, score, img, id, type FROM artists WHERE type = ? ORDER BY score DESC LIMIT ?, ?");
$results->bind_param("sii", $typesql, $position, $item_per_page);
$results->execute();
$results->bind_result($name, $location, $score, $img, $id, $type);
} else {
$results = $mysqli->prepare("SELECT name, location, score, img, id, type FROM artists ORDER BY score DESC LIMIT ?, ?");
$results->bind_param("ii", $position, $item_per_page);
$results->execute();
$results->bind_result($name, $location, $score, $img, $id, $type);
}
// Le fetch
while($results->fetch()){
//my cards here
}
?>
I'm looking for ultimately hooking my search box to this query which is not working, I've tried to add alter the query to the below for testing purpose:
SELECT name, location, score, img, id, type FROM artists WHERE name LIKE '%etc%' ORDER BY score DESC LIMIT ?, ?
and I do have a name that has "etc" in it but the result I get is:
Call to a member function bind_param() on boolean in
How do I change this query to bind the $_GET result from the searchbox to it, the website is Setch.me
As in this question you can use LIKE with a bound parameter in mysqli:
$param = "%{$_POST['searchphrase']}%";
$stmt = $mysqli->prepare("SELECT name, location, score, img, id, type FROM artists WHERE name LIKE ?");
$stmt->bind_param("s", $param);
$stmt->execute();
$stmt->bind_result($name, $location, $score, $img, $id, $type);

A select that is not working

I have a select that doesn't work.
$person = mysql_query ("Select personID from persons order by personID desc Limit 0,1");
$query_string = 'INSERT INTO topics (topic,
description,
abstract,
personID)
VALUES (?, ?, ?, ?)';
$query = $db->prepare($query_string);
$query->execute(array($_POST['topic'],
$_POST['description'],
$_POST['abstract'],
$person));
I dont understand where is the problem
$person is a mysql result, not any kind of value.
Try this:
list($person) = mysql_fetch_row(mysql_query("select personID from ....."));
Here is the problem...
$person = mysql_query ("Select personID from persons order by personID desc Limit 0,1");
Do this...
$result = mysql_query ("Select personID from persons order by personID desc Limit 0,1");
$row = mysql_fetch_array($result);
$person = $row['personID'];
you are mixing to fetch mysql inside mysqli try this.
$person = $db->prepare("Select personID from persons order by personID desc Limit 0,1");
$person->execute();
$person->store_result();
$person->bind_result( $personID ) ; // to bind the result as variable to use it later
$person->fetch();
$query_string = 'INSERT INTO topics (topic,
description,
abstract,
personID)
VALUES (?, ?, ?, ?)';
$query = $db->prepare($query_string);
$query->execute(array($_POST['topic'],
$_POST['description'],
$_POST['abstract'],
$personID));
$dbh = new PDO('mysql:host='.$server.';dbname='.$db, $user, $pass);
$st=$dbh->prepare('Select personID from persons order by personID desc Limit 0,1');
$st->execute();
$result=$st->fetchAll();
//FOR TEST PURPOSE TO MAKE IT EASY.
echo "<pre>";
print_r($result);
echo "</pre>";
//END TEST
echo $result[0]['personID'];
Try this PDO code to select and use data.PDO is a prefererred way. and also instead of mysql use mysqli.
we are unclear about your concern. it would be better if you copy paste the error message or make us clear by editing you post, saying what actually you want and what you are unable to do. hope my help works!!

Replacing "?" in a string by values from array

I'm trying to replace every "?" in string by values from array. Each "?" is the next value from array.
I was wondering if there is a better way to do the following:
$query = 'SELECT * FROM pages WHERE id = ? AND language = ?';
$values = array('1', 'en');
foreach ($values as $value) {
$query = preg_replace('/\?/', '\''.$value.'\'', $query, 1);
}
echo '<pre>'.print_r($query, true).'</pre>';
Would like to do that with native PHP (not a PDO extension).
Use binding
in PDO
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour');
$sth->bindValue(':calories', $calories, PDO::PARAM_INT);
$sth->bindValue(':colour', $colour, PDO::PARAM_STR);
$sth->execute();
http://php.net/manual/pl/pdostatement.bindvalue.php
in mysqli
$stmt = $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
$stmt->bind_param('sssd', $code, $language, $official, $percent);
http://www.php.net/manual/en/mysqli-stmt.bind-param.php
if you want to do it in STUPID way you can use loop or recursion
$select = "SELECT * FROM pages WHERE id = ? AND language = ?";
$params = array('param', 'param2');
while(preg_match('/\?/', $select)) $select = str_replace("?", array_shift($params), $select);
but it's stupid
Mysqli and PDO are as native as it gets with PHP.
You can use bind_param from mysqli to accomplish this. Example:
$stmt = $mysqli->prepare("SELECT * FROM pages WHERE id = ? AND language = ?");
$stmt->bind_param('is', 1, "en");
In this case the i and s are referencing the type of the parameter, as seen in this table (available in link):
i corresponding variable has type integer
d corresponding variable has type double
s corresponding variable has type string
b corresponding variable is a blob and will be sent in packets

Categories