How to insert a mixed string using mysqli_bind_param prepared statements - php

I've been searching for an answer for a while now, but can't seem to find anything.
I'm looking for a way to use mysqli_bind_param to insert a row into a table, where the param (?) is part of a larger string.
This is my code:
$query = "INSERT INTO CDBusers_activity (order_ID, activity_text_desc) VALUES (?, 'Price edited from ? to ?')";
$stmt = mysqli_prepare($DB_conn, $query);
mysqli_bind_param($stmt, "sss", $orderID, $product_editPrice_was, $product_editPrice_now);
mysqli_stmt_execute($stmt);
I'm looking for a way to add the $product_editPrice_was and $product_editPrice_now into the row.
I could create a string:
$text = "Price edited from $product_editPrice_was to $product_editPrice_now"
and then bind that, but I am interested if there is a simpler way? For example:
$query = "INSERT INTO CDBusers_activity (order_ID, activity_text_desc) VALUES (?, 'Price edited from ' ? ' to ' ?)";

Asking your primary question - no, you can't replace part of inserted value with a placeholder.
The solution is:
$query = "INSERT INTO CDBusers_activity (order_ID, activity_text_desc) VALUES (?, ?)";
$stmt = mysqli_prepare($DB_conn, $query);
$text = "Price edited from $product_editPrice_was to $product_editPrice_now";
mysqli_bind_param($stmt, "ss", $orderID, $text);
mysqli_stmt_execute($stmt);
Another solution is to create to different fields like price_before, price_after.
But if you can't do it, you can try using mysql CONCAT() and placeholders for example, but i'm not sure if it works:
INSERT INTO CDBusers_activity (order_ID, activity_text_desc) VALUES (?, CONCAT('Price edited from ', ?, ' to ', ?)

but I am interested if there is a simpler way?
This is an interesting question. In a way.
$text = "Price edited from $product_editPrice_was to $product_editPrice_now";
is apparently the easiest way to create a text string. While this text string can be bound to a query the usual way with a placeholder. Besides, you will have your SQL and data separated from each other, which will help you to organize your code better.
So I think that there are things you should not make simpler. Because such an attempt will likely make things more complex.

Related

How to use PHP prepare with zillions of fields of different types

I am inserting data that has VARCHAR, TIMESTAMP and DECIMAL kinds using prepare.
The data is already in the format needed by mySQL.
My problem is this. Suppose I had only 2 items to insert. I would do like this:
$stmt = $mysqli->prepare("INSERT INTO myTable (name, age) VALUES (?, ?)");
$stmt->bind_param("si", $_POST['name'], $_POST['age']);
My problem is the bind part. How do I do the bind when I have to insert 40 columns at once?
I can deal with the prepare part by doing this:
$sql = "INSERT INTO customers ($columns) VALUES ($values)";
$stmt = $mysqli->prepare($sql);
But the next line will result in a ridiculous long line, impossible to understand and very easy to go wrong.
$stmt->bind_param("ssssiidisisssiidiisssidiisidi", ....);
I don't see how I could build that in a loop for example.
How do I do that?
You can pass an array to the mysqli_stmt::bind_param() function as variable arguments with the ... syntax, introduced in PHP 5.6.
$params = ['name', 42];
$stmt = $mysqli->prepare("INSERT INTO myTable (name, age) VALUES (?, ?)");
$stmt->bind_param(str_repeat('s', count($params)), ...$params);
$stmt->execute();
You don't really need to set the data type individually for each column. You can treat them all as 's'.
I know you're asking about mysqli, but I'll just point out that this is easier with PDO:
$params = ['name', 42];
$stmt = $pdo->prepare("INSERT INTO myTable (name, age) VALUES (?, ?)");
$stmt->execute($params);

Inserting thousands of rows in one query MySQL using PHP

I have tried whole day (again) but with error trying to insert in total of over billion of rows while inserting about 10k within one query. I want to use prepared statements to do this with MySQL, using innoDB tables. Hardware resources are not a problem, problem has all the time been indexing and one row / insert.
Do not say that I should use straight from list methods since I need to do some calculations before inserting. Input comes from file.
So I have a big while loop, looping text file lines and that's working fine.
I currently do it with inserting one per query.
$stmt = $conn->prepare("INSERT INTO $tableName(row1, row2, row3) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $str1, $str2, $str3);
$stmt->execute();
I have looked at examples doing it like so:
$stmt = $conn->prepare("INSERT INTO $tableName(row1, row2, row3) VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?), (?, ?, ?) ..... ");
But I need to construct this to for like 5-10k rows for single query.
If someone has done something like this before, please give some reference to work with.
Thanks in advance!
The whole idea of a prepared query is that it reduces the overhead of setting up the query each time it's run – prepare once, execute repeatedly. That means there's not going to be a huge amount of difference (from the POV of the database) between running a prepared statement in a loop, or passing one giant query.
You don't include your whole code here, but an error that many people make is to include the statement preparation in the loop. Don't make that mistake! Something like this will be most efficient:
// these need a value before being used in bind_param
$str1 = $str2 = $str3 = "";
$stmt = $conn->prepare("INSERT INTO $tableName(row1, row2, row3) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $str1, $str2, $str3);
while ($we_have_data) {
$str1 = "foo";
$str2 = "bar";
$str3 = "baz";
$stmt->execute();
}
Though I always recommend using PDO prepared statements, as you get to avoid the potential mess of binding parameters:
// assuming $conn is a PDO object now
$stmt = $conn->prepare("INSERT INTO $tableName(row1, row2, row3) VALUES (?, ?, ?)");
while ($we_have_data) {
$str1 = "foo";
$str2 = "bar";
$str3 = "baz";
$stmt->execute([$str1, $str2, $str3]);
}
Maybe because limit executing time from server. Try to use insert batch.
Add to array
$i = 0;
.. looping
$i++;
$mark[] = '(?,?,?)';
$val[] = $str1.",".$str2.",".$str3;
// check when 1k record
if($i == 1000){
$stmt = $conn->prepare("INSERT INTO ? (row1, row2, row3) VALUES ".implode(',', $mark);
$stmt->bind_param("sss", implode(',', $val));
$stmt->execute();
$mark = []; $val = []; $i = 0; // reset
}

inserting data from a form into your mysql database using php

i used this code
<?php
$conn = new PDO("mysql:host=localhost;dbname=CU4726629",'CU4726629','CU4726629');
$sql="INSERT INTO review (username, movie_name, ratings) VALUES ("$_POST['username']","$_POST['moviename']","$_POST['ratings']")";
header('Location: reviews.php');
?>
but it keeps giving me this error
Parse error: syntax error, unexpected T_VARIABLE in
/home/4726629/public_html/check_login.php on line 5
Take this for an example:
<?php
// insert some data using a prepared statement
$stmt = $dbh->prepare("insert into test (name, value) values (:name, :value)");
// bind php variables to the named placeholders in the query
// they are both strings that will not be more than 64 chars long
$stmt->bindParam(':name', $name, PDO_PARAM_STR, 64);
$stmt->bindParam(':value', $value, PDO_PARAM_STR, 64);
// insert a record
$name = 'Foo';
$value = 'Bar';
$stmt->execute();
// and another
$name = 'Fu';
$value = 'Ba';
$stmt->execute();
// more if you like, but we're done
$stmt = null;
?>
You just wrote a string in your above code:
$sql="INSERT INTO review (username, movie_name, ratings) VALUES ("$_POST['username']","$_POST['moviename']","$_POST['ratings']")";
Above answers are correct, you will need to concat the strings to form a valid sql query. you can echo your $sql variable to check what is to be executed and if is valid sql query or not. you might want to look in to escaping variables you will be using in your sql queries else your app will be vulnerable to sql injections attacks.
look in to
http://php.net/manual/en/pdo.quote.php
http://www.php.net/manual/en/pdo.prepare.php
Also you will need to query you prepared sql statement.
look in to http://www.php.net/manual/en/pdo.query.php
A couple of errors:
1) you have to concat the strings!
like this:
$sql="INSERT INTO review (username, movie_name, ratings)
VALUES (".$_POST['username'].",".$_POST['moviename'].",".$_POST['ratings'].")";
2) you are not using the PDO at all:
after you create the "insert" string you must query the db itself, something like using
$conn->query($sql);
nb: it is pseudocode
3) the main problem is that this approach is wrong.
constructing the queries in this way lead to many security problems.
Eg: what if I put "moviename" as "; drop table review;" ??? It will destroy your db.
So my advice is to use prepared statement:
$sql="INSERT INTO review (username, movie_name, ratings)
VALUES (?,?,?)";
$q = $conn->prepare($sql);
$fill_array = array($_POST['username'], $_POST['moviename'], $_POST['ratings']);
$q->execute($fill_array);
You forgot dots:
$sql="INSERT INTO review (username, movie_name, ratings)
VALUES (".$_POST['username'].",".$_POST['moviename'].",".$_POST['ratings'].")";
and fot the future for now your variables are not escaped so code is not secure
String in a SQL-Statment need ', only integer or float don't need this.
$sql="INSERT INTO review (username, movie_name, ratings) VALUES ('".$_POST['username']."','".$_POST['moviename']."','".$_POST['ratings']."')";

If I use $_POST value directly in bindParam (mysqli) will there be a security issue?

I have been reading about using $_POST values being used directly in isert statements and understand that this is an invitation for trouble. What is not clear in any of the posts I read was -
Say my form is sending 7 items to my mysqli insertion script and I use the posted values like this:
$stmt = $mysqli->prepare("INSERT INTO `advertisements` (`from`, `r_u_res`, `email`, `blockname`, `floorno`, `doorno`, `content`) VALUES (?, ?, ?, ?, ?,?,?)");
$stmt->bind_param('sssssss', $_POST['from'], $_POST['rures'], $_POST['email'], $_POST['blockname'], $_POST['floorno'], $_POST['doorno'], $_POST['content']);
$stmt->execute();
$stmt->close();
Would that be the correct way to do it? Or should I first store the posted values in a new variable and use that variable while binding? - like this :
$postedfrom = $_POST['from'];
$postedrures = $_POST['rures'];
$postedemail = $_POST['email'];
$postedblockname = $_POST['blockname'];
$postedfloorno = $_POST['floorno'];
$posteddoorno = $_POST['doorno'];
$postedcontent = $_POST['content'];
$stmt = $mysqli->prepare("INSERT INTO `advertisements` (`from`, `r_u_res`, `email`, `blockname`, `floorno`, `doorno`, `content`) VALUES (?, ?, ?, ?, ?,?,?)");
$stmt->bind_param('sssssss', $postedfrom, $postedrures, $postedemail, $postedblockname, $postedfloorno, $posteddoorno, $postedcontent);
$stmt->execute();
$stmt->close();
I saw a post OO mysqli prepared statements help please where the answer does seem to be like the code above but I want to know whether doing it like the first code poses security issues...
both forms are equivalent from a security perspective as php first resolves the values to be passed in the method call to $stmt->bind_param, thus that function sees the exact same values in both cases.
ps: both snippets look ok to me.

mysql query works sometimes but not always

I'm building a simple "little" movie cataloging database system for my own use. The problem right now is that I've got a mySQL query that works MOST of the time but not all. Basically it works by using a 3rd party IMDB API. I use that to search and pull the values I need which works just fine. It displays on my preview screen and everything. The problem I'm running into that that while most movies work, a few do not and I can't figure out the reason.
For example, The Fellowship of the Ring stores just fine while The Return of the King simply won't pass the query. I can't find any differences.
Here's my query:
$query = "INSERT INTO movies
(title, year, releaseDate, actors, image, runtime, genre, director, rating, watchedDate, category, series, comments, owned, ownedFormat, seen, plot, favorite, uploadDate)
VALUES ('$title', '$year', '$releaseDate', '$actors', '$newImg', '$runtime', '$genre', '$director', '$rating', '$watchedDate', '$category', '$series', '$comments', '$owned', '$ownedFormat', '$seen', '$plot', '$favorite', '$curDate')";
mysql_query($query) or die ('Error');
I'm not sure what else I need to provide. It seems like some kind of difference in the movies is causing the error but I don't know.
Thanks!
** EDIT ***
So I tried switching over to mysqli. Here's my new code:
/* Create the prepared statement */
if ($stmt = $mysqli->prepare("INSERT INTO movies (title, year, releaseDate, actors, image, runtime, genre, director, rating, watchedDate, category, series, comments, owned, ownedFormat, seen, plot, favorite, uploadDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")) {
/* Bind our params */
$stmt->bind_param('sssssssssssssssssis', $title, $year, $releaseDate, $actors, $newImg, $runtime, $genre, $director, $rating, $watchedDate, $category, $series, $comments, $owned, $ownedFormat, $seen, $plot, $favorite, $curDate);
/* Execute the prepared Statement */
$stmt->execute();
/* Echo results */
echo "Inserted {$title} into database\n";
}
However, now i'm getting an error that reads:
Fatal error: Call to a member function prepare() on a non-object on the line where the if statement starts.
I'm assuming this is because something my query isn't an object?
Thanks
The most likely reason for this is that you are putting the raw values between single quotes. If one of the values has a single quote in it, then you will get a syntax error.
A better way to do what you want is by binding parameters. You can read more about that here.
Without more information about the actually returned value it is hard to say. It is possible that the returned value contains a character that breaks your code such as a semicolon or quote. Try stripping all non alphanumeric characters away using regex.
$result = preg_replace("/[^a-zA-Z0-9]+/", "", $s);
And you have a sql injection vulnerablility. Consider using PDO instead of the depreciacted mysql functions.
http://php.net/manual/en/book.pdo.php

Categories