Replacing "?" in a string by values from array - php

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

Related

PHP MySQL SELECT Statement with bindparam doesn't work

This is my code:
function getUsers($connection ,$username) {
$sql = "SELECT * FROM users where username = ?";
$stmt = $connection->prepare($sql);
$stmt->bindParam("s", $username, PDO::PARAM_STR);
return $stmt->fetchAll();
}
$voornaam = "dave";
$users = getUsers($connection, $voornaam);
print_r($users);
When I open my webpage, I get an empty Array.
I checked, and there is a user with the username "dave" in my database.
This should work, however, it doesn't...
Anyone knows what I did wrong?
Thanks in advance.
First is, you have to execute it before using fetchAll():
$stmt->execute();
$result = $stmt->fetchAll();
This is the correct way:
$stmt = $connection->prepare('SELECT * FROM users where username = :username');
$stmt->bindParam(':username', $username);
If you want to user ? it will determine the order of ? in bindParam, use it like this:
$sql = "SELECT * FROM users where username = ?";
$stmt = $connection->prepare($sql);
$stmt->bindParam(1, $username, PDO::PARAM_STR);
More example:
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?');
$sth->bindParam(1, $calories, PDO::PARAM_INT);
$sth->bindParam(2, $colour, PDO::PARAM_STR, 12);
Instead of using
$stmt->bindParam("s", $username, PDO::PARAM_STR);
you need to use
$stmt->bindParam(1, $username, PDO::PARAM_STR);
Check this link for details https://www.php.net/manual/en/pdostatement.bindparam
You need to check this Example #2 Execute a prepared statement with question mark placeholders
This is the correct way
$sql = "SELECT * FROM users where username = ?";
$stmt = $conn->prepare($sql);
$stmt->bindParam(1, $username, PDO::PARAM_STR);
$stmt->execute();
return $stmt->fetchAll();

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);
}

Php PDO, Insert a changable varible

TEST WEBSITE: csgodice.co.uk
I've been looking into PDO, but it confuses me, i am only 14 and im not that knowledge about mysql in php all i know is to use PDO and some parts of databases, i was wondering how i would insert a changable value, such as balance, here is my information i want to insert into my table as rows
$conn->prepare("INSERT INTO users (64ID, BALANCE, AMOUNTBET) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $64id, $balance, $amountbet );
// set parameters and execute
$_64id = "$steamprofile['steamid']";
$balance = "";
$amountbet = "";
$stmt->execute();
I Have connected to my mysql so all that is done, all i really need to know is how to insert rows? i know there is documentation about it but the topics on there differ to what i am trying to do?
Take from PHP documentation http://php.net/manual/en/pdostatement.bindparam.php
<?php
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();
?>
so your code will be:
$stmt = $conn->prepare("INSERT INTO users (64ID, BALANCE, AMOUNTBET) VALUES (:_64id, :balance, :amountbet)");
$_64id = $steamprofile['steamid'];
$balance = "";
$amountbet = "";
$stmt->bind_param(:_64id, $_64id);
$stmt->bind_param(:balance, $balance);
$stmt->bind_param(:amountbet, $amountbet);
$stmt->execute();

PHP - Converting PDO to normal code

I was wondering if someone could help me.
Im trying to integrate some code into my application, the code that i need to integrate is written with PDO statements and i have no idea how it goes.
I was wondering if someone could help me convert it.
The code is as follows
$sql = "insert into message2 (mid, seq, created_on_ip, created_by, body) values (?, ?, ?, ?, ?)";
$args = array($mid, $seq, '1.2.2.1', $currentUser, $body);
$stmt = $PDO->prepare($sql);
$stmt->execute($args);
if (empty($mid)) {
$mid = $PDO->lastInsertId();
}
$insertSql = "insert into message2_recips values ";
$holders = array();
$params = array();
foreach ($rows as $row) {
$holders[] = "(?, ?, ?, ?)";
$params[] = $mid;
$params[] = $seq;
$params[] = $row['uid'];
$params[] = $row['uid'] == $currentUser ? 'A' : 'N';
}
$insertSql .= implode(',', $holders);
$stmt = $PDO->prepare($insertSql);
$stmt->execute($params);
You shoudl use PDO unles for some technical reason you cant. If you dont know it, learn it. Maybe this will get you started:
/*
This the actual SQL query the "?" will be replaced with the values, and escaped accordingly
- ie. you dont need to use the equiv of mysql_real_escape_string - its going to do it
autmatically
*/
$sql = "insert into message2 (mid, seq, created_on_ip, created_by, body) values (?, ?, ?, ?, ?)";
// these are the values that will replace the ?
$args = array($mid, $seq, '1.2.2.1', $currentUser, $body);
// create a prepared statement object
$stmt = $PDO->prepare($sql);
// execute the statement with $args passed in to be used in place of the ?
// so the final query looks something like:
// insert into message2 (mid, seq, created_on_ip, created_by, body) values ($mid, $seq, 1.2.2.1, $currentUser, $body)
$stmt->execute($args);
if (empty($mid)) {
// $mid id is the value of the primary key for the last insert
$mid = $PDO->lastInsertId();
}
// create the first part of another query
$insertSql = "insert into message2_recips values ";
// an array for placeholders - ie. ? in the unprepared sql string
$holders = array();
// array for the params we will pass in as values to be substituted for the ?
$params = array();
// im not sure what the $rows are, but it looks like what we will do is loop
// over a recordset of related rows and do additional inserts based upon them
foreach ($rows as $row) {
// add a place holder string for this row
$holders[] = "(?, ?, ?, ?)";
// assign params
$params[] = $mid;
$params[] = $seq;
$params[] = $row['uid'];
$params[] = $row['uid'] == $currentUser ? 'A' : 'N';
}
// modify the query string to have additional place holders
// so if we have 3 rows the query will look like this:
// insert into message2_recips values (?, ?, ?, ?),(?, ?, ?, ?),(?, ?, ?, ?)
$insertSql .= implode(',', $holders);
// create a prepared statment
$stmt = $PDO->prepare($insertSql);
// execute the statement with the params
$stmt->execute($params);
PDO really is better. It has the same functionality as MySQLi but with a consistent interface across DB drivers (ie. as long as your SQL is compliant with a different database you can theoretically use the exact same php code with mysql, sqlite, postresql, etc.) AND much better parameter binding for prepared statements. Since you shouldnt be using the mysql extension any way, and MySQLi is more cumbersome to work with than PDO its really a no-brainer unless you specifically have to support an older version of PHP.

php mysqli prepared statement

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

Categories