function update_review($link, $user_id, $game_id, $rating, $title, $review) {
$sql = "UPDATE reviews SET rating = ?, title = ?, review = ? WHERE user_id = ? AND game_id = ?";
$stmt = $link->prepare($sql);
if ( !$stmt ) {
die("could not prepare statement: " . $link->errno . ", error: " . $link->error);
}
$stmt->bind_param("sssii", $rating, $title, $review, $user_id, $game_id);
if ( !$stmt ) {
die("could not bind params: " . $stmt->error);
}
if ( !$stmt->execute() ) {
die("couldn't execute statement");
}
}
function update_review2($link) {
$sql = "update reviews set rating = \"43\", title = \"test\", review = \"blah\" where user_id = \"5\" and game_id = \"1\"";
$stmt = $link->prepare($sql);
if ( !$stmt ) {
die("could not prepare statement: " . $link->errno . ", error: " . $link->error);
}
if ( !$stmt->execute() ) {
die("couldn't execute statement");
}
}
var_dump($review_data);
// output = array(5) { ["user_id"]=> int(5) ["game_id"]=> int(1) ["rating"]=> string(2) "43" ["title"]=> string(4) "test" ["review"]=> string(4) "blah" }
update_review($link, $review_data['rating'], $review_data['title'], $review_data['review'], $review_data['user_id'], $review_data['game_id']);
Going to be honest, done the usual uni student thing and left the assignment to last min and regretting it again...
Anyways been trying to figure this out for a few hours now and i've come to a loss, ive made it work by not using prepared statements as you can see above in the update_review2 function however when using the prepared statements version update_review it does not affect any rows in the db. If anyone can offer a bit of help it will be greatly appreciated especially because the deadline is in 6 hours!
Based on your above code the function call to update_review() has variables in one order while the function itself is declared with variables in another order.
Because of that, you might be passing a string when the statement is expecting an int.
Related
I have been using the traditional method of query db with out prepared statement. So decided to move to prepared statement now as below are my codes.
$link = new mysqli(dbHost, dbUser, dbPassword, dbDatabase);
if($link->connect_error) {
die('bind_param() failed: ' . htmlspecialchars($link->connect_error));
}
$stmt = $link->stmt_init();
$selectQuery1 ="Select * From tblUser Where tblUser.userName=? ";
$stmt1 = mysqli_prepare($link, $selectQuery1);
if ( false===$stmt1 ) {
die('stmt1 prepare() failed: ' . htmlspecialchars($mysqli->error));
}
$rc1 = $stmt1->bind_param('s', $userName);
if ( false===$rc ) {
die('rc1 bind_param() failed: ' . htmlspecialchars($stmt1->error));
}
$execute1 = $stmt1->execute();
if ( false===$execute1 ) {
die('execute1 execute() failed: ' . htmlspecialchars($stmt1->error));
}
$store1=$stmt1->store_result();
if ( false===$store1 ) {
die('store1() failed: ' . htmlspecialchars($stmt1->error));
}
$count1=$stmt1->num_rows;
$result1 = $stmt1->get_result();
if ( false===$result1 ) {
die('result1 () failed: ' . htmlspecialchars($stmt1->error));
}
The query worked well till this line $count1=$stmt1->num_rows; and the moment I put this codes $result1 = $stmt1->get_result(); my page failed and I found out that I must now change to mysql native driver etc. My biggest worry is by changing the driver it might effect all my other existing application. So what is the best mechanism to mitigate is there any other method to retrieve the result or move to PDO ? I want to be able to use this mechanism mysql_fetch_array($result, MYSQL_ASSOC) to get my select results ?
So, I am passing arrays of values that will vary upon use into a method that then inserts them into a database. My problem is the way in which the parameters are bound.
public function insertValues($table, $cols, $values)
{
$mysqli = new mysqli(DBHOST, DBUSER, DBPASSWORD, DBDATABASE);
$colString = implode(', ', $cols); // x, x, x
$valString = implode(', ', array_fill(0, count($values), '?')); // ?, ?, ?
$sql = "INSERT INTO $table ($colString) VALUES($valString)";
if (!$stmt = $mysqli->prepare($sql))
echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
// THIS IS THE PROBLEM AREA
foreach ($values as $v)
if (!$stmt->bind_param('s', $v))
echo "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error;
if (!$stmt->execute())
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
$stmt->close();
$mysqli->close();
}
I need a way to bind all the parameters at once I think, and not one at a time, but I can't figure out a useful way to do this. Any help would be greatly appreciated.
I found the answer for the problem you are looking for on PHP.net (http://php.net/manual/en/mysqli-stmt.bind-param.php). I'm pasting it here for convenience, all credit goes to a man going by the email Nick9v ^ät^ hotmail -remove- -dot- com
When dealing with a dynamic number of field values while preparing a
statement I find this class useful.
[Editor's note: changed BindParam::add() to accept $value by reference
and thereby prevent a warning in newer versions of PHP.]
<?php
class BindParam{
private $values = array(), $types = '';
public function add( $type, &$value ){
$this->values[] = $value;
$this->types .= $type;
}
public function get(){
return array_merge(array($this->types), $this->values);
}
}
?>
Usage is pretty simple. Create an instance and use the add method to populate. When you're ready to execute simply use the get method.
<?php
$bindParam = new BindParam();
$qArray = array();
$use_part_1 = 1;
$use_part_2 = 1;
$use_part_3 = 1;
$query = 'SELECT * FROM users WHERE ';
if($use_part_1){
$qArray[] = 'hair_color = ?';
$bindParam->add('s', 'red');
}
if($use_part_2){
$qArray[] = 'age = ?';
$bindParam->add('i', 25);
}
if($use_part_3){
$qArray[] = 'balance = ?';
$bindParam->add('d', 50.00);
}
$query .= implode(' OR ', $qArray);
//call_user_func_array( array($stm, 'bind_param'), $bindParam->get());
echo $query . '<br/>';
var_dump($bindParam->get());
?>
This gets you the result that looks something like this:
SELECT * FROM users WHERE hair_color = ? OR age = ? OR balance = ?
array(4) { [0]=> string(3) "sid" 1=> string(3) "red" [2]=> int(25) [3]=> float(50) }
The code doesn't work because bind_param has to have all of the query parameters in a single call to the function instead of multiple calls for each parameter, also it needs variables passed by reference, so in the foreach call it would always be the same variable with the value that it had in the last iteration of the loop.
The easiest way would be to compose an array with the types and parameters, and then pass it to bind_param with a call to call_user_func_array, for example:
$params = array();
$types = '';
foreach ($values as $k => $v)
{
$types .= 's';
$params[] = &$values[$k];
}
$bind_params = array_merge(array($types), $params);
if (!call_user_func_array(array($stmt, 'bind_param'), $bind_params))
// ...
Note that bind_param expects variables to be passed by reference not by value, otherwise it would be a couple of lines constructing an array with values, instead of the foreach loop.
I'm new to mysqli, I wrote a function as below.
1 - I couldn't find a way for SELECT * query and having bind_result to assign each column value to the same name variable. (e.g. name column value of #row stores to $name)
I think bind_result() has no function on a SELECT * query?
2 - So I tried another option, to fetch all rows and assign them to appropriate variable manually through a loop. I think I should use $query->fetch_all() or $query->fetch_assoc() for looping but I encounter with this:
Fatal error: Call to undefined method mysqli_result::fetch_all()
or
Fatal error: Call to undefined method mysqli_result::fetch_assoc()
However I did a phpinfo() and saw mysqlnd was enabled and php version is 5.4.7 (running XAMPP v1.8.1)
And 3- what finally I did is below idea that doesn't work either.
function the_names($name)
{
global $db;
if($query = $db->prepare("SELECT * FROM users where name=?"))
{
$query->bind_param('s', $name);
if($query->execute())
{
$query->store_result();
if($query->num_rows > 1)
{
while($row = $query->fetch())
{
echo $row['name']; // Here is the problem
}
}
else
echo "not valid";
$query->close();
}
}
}
I need a way to store all fetched data as what bind_result() does, or having them in an array for later use, and it's much better to know both. tnx
One word to answer all your questions at once - PDO
It has everything you are trying to get from mysqli (in vain):
function the_names($name)
{
global $db;
$query = $db->prepare("SELECT * FROM users where name=?");
$query->execute(array($name));
return $query->fetchAll();
}
$names = the_names('Joe');
foreach ($names as $row) {
echo $row['name'];
}
Note the proper way of using a function. it should never echo anything, but only return the data for the future use
If your mysqli code doesn't have binding_param() you can just write code like below :
$mysqli = new mysqli("localhost" , "root" , "" , "database_name");
$result = $mysqli->query( "SELECT * FROM users where name=" . $name) ;
while ( $row = $result->fetch_assoc() ) {
echo $row["name"];
}
If you use binding_param() code , you also need to set bind_result()
$db = new mysqli("localhost" , "root" , "" , "database_name");
function the_names($name){
global $db;
/* Prepared statement, stage 1: prepare */
if (!($query = $db->prepare("SELECT * FROM users where name=?"))) { # prepare sql
echo "Prepare failed: (" . $db->errno . ") " . $db->error;
}
/* Prepared statement, stage 2: bind and execute */
if (!$query->bind_param("s", $name)) { # giving param to "?" in prepare sql
echo "Binding parameters failed: (" . $query->errno . ") " . $query->error;
}
if (!$query->execute()) {
echo "Execute failed: (" . $query->errno . ") " . $query->error;
}
$query->store_result(); # store result so we can count it below...
if( $query->num_rows > 0){ # if data more than 0 [ that also mean "if not empty" ]
# Declare the output field of database
$out_id = NULL;
$out_name = NULL;
$out_age = NULL;
if (!$query->bind_result($out_id, $out_name , $out_age)) {
/*
* Blind result should same with your database table !
* Example : my database
* -users
* id ( 11 int )
* name ( 255 string )
* age ( 11 int )
* then the blind_result() code is : bind_result($out_id, $out_name , $out_age)
*/
echo "Binding output parameters failed: (" . $query->errno . ") " . $query->error;
}
while ($query->fetch()) {
# print the out field
printf("id = %s <br /> name = %s <br /> age = %s <br />", $out_id, $out_name , $out_age);
}
}else{
echo "not valid";
}
}
the_names("panji asmara");
Reference :
http://php.net/manual/en/mysqli.quickstart.prepared-statements.php
I have a query that works in phpmyadmin however does not work in my code! I have tried various variable dumps to see if I have been loosing data before the query is executed, all seems ok, the same variables contents I have used in the successful query in phpmyadmin
To test I replaced:
$account_id = $account->getAccountId(); //output below
string(2) "59" string(4) "main" NULL NULL array(2) { ["id"]=> NULL["name"]=>NULL}
With
$account_id = 59; //output below
int(59) string(4) "main" NULL NULL array(2) { ["id"]=> NULL ["name"]=> NULL }
below is the code extract and I am using mysqli:
$account = $Add_Profile_Image->getUserAccount();
$account_id = $account->getAccountId();
$status = $account->getType();
var_dump($account_id);
var_dump($status);
$conn = $this->create_connection('read');
$stmt = $conn->prepare('SELECT add_profile_images.image_id, image_name FROM add_profile_images, users_profile_images WHERE users_profile_images.account_id=? AND users_profile_images.status=?');
$stmt->bind_param('is',$account_id,$status);
$stmt->bind_result($id,$imageName);
$stmt->execute();
var_dump($id);
var_dump($imageName);
$result['id'] = $id;
$result['name'] = $imageName;
I have replaced
image_name //in the query
To
add_profile_images.image_name //in the query
but the result is still NULL?
So I have tried the following examples in this post: PHP Prepared Statement Returns -1
When I dump the mysqli object it does return -1 however when I implement the below no errors
are shown!
if($conn->connect_error) {
printf('connect error (%d) %s', $conn->connect_errno, htmlspecialchars($conn->connect_error));
die;
}
$stmt = $conn->prepare('SELECT add_profile_images.image_id, add_profile_images.image_name FROM add_profile_images, users_profile_images WHERE users_profile_images.account_id=? AND users_profile_images.status=?');
if ( false===$stmt ) {
printf('prepare failed: %s', htmlspecialchars($conn->error));
die;
}
$rc = $stmt->bind_param('is',$account_id,$status);
if ( false===$rc ) {
printf('bind_param failed: %s', htmlspecialchars($stmt->error));
die;
}
$rc= $stmt->execute();
if ( false===$rc ) {
printf('execute failed: %s', htmlspecialchars($stmt->error));
die;
}
$rc = $stmt->bind_result($id,$imageName);
if ( false===$rc ) {
printf('bind_result failed: %s', htmlspecialchars($stmt->error));
die;
}
Where am I going wrong?
Hope someone can help!
Thanks
You need to state $stmt->bind_result() AFTER $stmt->execute()
(see: http://php.net/manual/en/mysqli-stmt.bind-result.php)
I Had the same problem the reason for that is closing the connection when using the statement prepare. make sure, in your flow there is no such closing of the connection
This has annoyed me for a while now. I am trying this query in phpmyadmin.
select `id` from `users` where `fb_id` = 507292797 limit 1
This returns the value 13, so why doesn't this work:
$sql = "select `id` from `users` " .
"where `fb_id` = :fb_id " .
"limit 1";
try
{
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':fb_id', $fb_id2, PDO::PARAM_INT);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
$result = $stmt->execute();
$stmt->closeCursor();
}
catch (Exception $e)
{
die ($e->getMessage() );
}
echo "id: " . $fb_id2 . " var_dump: " . var_dump($user);
exit();
This returns:
id: 507292797 var_dump: bool(false)
When var_dump should return $user['id'] = 13
Can somebody see what I am doing wrong here?
ps. here is my db connection function if that matter
$dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME;
$driver_options = array( PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8' );
try
{
$this->db = new PDO($dsn, DB_USER, DB_PASS, $driver_options);
You are doing things in this order :
Preparing the statement
Binding the variables
Trying to fetch data from the statement
Executing the statement
The two last steps should be in the inverse order : you must execute the statement before you can fetch data (that's obtained by executing it).
Basically, instead of using this :
// fetch, then execute ???
$user = $stmt->fetch(PDO::FETCH_ASSOC);
$result = $stmt->execute();
You should use that :
// Execute, **then** fetch
$stmt->execute();
$user = $stmt->fetch(PDO::FETCH_ASSOC);
Looks like you are fetching before executing?