Prevent PHP from attempting to perform mathematical calculations on a string - php

So I'm using PHP to take the contents of a csv file, put it into a string array and then use SQL to add it to a database on an IBM iSeries.
However PHP keeps trying to treat the contents of the string (which contains special characters like "*" and "-") like a mathematical computation.
How do I prevent this?
here is the code in question
if (($handle = fopen($_FILES['uploadcsv']['tmp_name'], "r")) !== FALSE)
{
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE)
{
$length = count($data);
$s_data = implode(',', $data);
if($length > $maxcol)
{
// echo $length;
// die;
$uploadMsg = "Data Error: Not ($maxcol) Columns: ($s_data) <br>";
}
else
{
if($data[0] <> '')
{
$recda[0] = trim($data[0]); // qty = 1 roll
// Prepare the SQL statement (possibly faster, safer, better practice)
$insertsql = "INSERT INTO MIKELIB/PALLETS (PALLET)
VALUES($recda[0]) with nc";
$stmt = db2_prepare($db2conn, $insertsql);
//$result = db2_exec($db2conn, "Insert into file ...$data[0]"
$result = db2_execute($stmt, $data[0]);
if(!$result)
{
$uploadMsg .= "Result code: " . $result . "Data Error: " . db2_stmt_error() . " msg: " . db2_stmt_errormsg() . "data: ($s_data)<br>";
}
else
{
$s_data = implode(',', $recda);
$uploadMsg .= "Added row ($s_data)<br>";
}
}
}
}
fclose($handle);
}
Here is an example output of the error "Result code: Data Error: 42604 msg: Numeric constant 5D09C not valid. SQLCODE=-103data: (A2501-0044*970*5D09C*034)"

Actually, it's your database that is parsing your data as math.
Take a look at this line:
$insertsql = "INSERT INTO MIKELIB/PALLETS (PALLET)
VALUES($recda[0]) with nc";
$stmt = db2_prepare($db2conn, $insertsql);
You're putting the values directly into the query, so if the query has math, or invalid symbols, it'll break your query.
What you should do is:
$insertsql = "INSERT INTO `MIKELIB/PALLETS` (PALLET)
VALUES(?) with nc";
$stmt = db2_prepare($db2conn, $insertsql);
$recda0 = $recda[0];
db2_bind_param($stmt, 1, "recda0", DB2_PARAM_IN);
That way, there's nothing in $recda[0] that will break the query, or be parsed as part of the query.

Joesph, try modifing your SQL to treat that value as a string by wrapping it in single quotes.
$insertsql = "INSERT INTO MIKELIB/PALLETS (PALLET)
VALUES('$recda[0]') with nc";
You may also need to consider escaping single quotes in the string if there is a possibility it will contain any.

I get the impression that you may be trying to load values into multiple columns per row. That won't work in SQL. You have to specify each column.
I know DB2 for i, but not PHP, so I'll attempt to build on David's answer as a template.
$insertsql = "INSERT INTO MYLIB/MYTABLE (cola, colb, colc)
VALUES(?,?,?) with nc";
$stmt = db2_prepare($db2conn, $insertsql);
$vala = $recda[0];
$valb = $recda[1];
$valc = $recda[2];
db2_bind_param($stmt, 1, "vala", DB2_PARAM_IN);
db2_bind_param($stmt, 2, "valb", DB2_PARAM_IN);
db2_bind_param($stmt, 3, "valc", DB2_PARAM_IN);
You may need additional PHP code, perhaps to make sure each value is appropriate for its column, and might perhaps need to detect missing values and load a null or default value, depending on your table definition. But I'll leave that to those who know PHP.

Related

How can I iterate through unique variable names when inserting values into Oracle?

In my PHP code, I have variables named/defined like this:
$comment_1 = $_POST["A_comment"];
$comment_2 = $_POST["B_comment"];
$comment_3 = $_POST["C_comment"];
I'm attempting to insert the values from these variables into Oracle using an iterative approach to provide the number being used at the end of each variable name, as shown here:
for($i=1;$i<4;$i++) {
$sql2 = "INSERT INTO i_avail(IA_COMMENTS) VALUES('$comment_$i')";
$stid2 = oci_parse($connect, $sql2);
$r = oci_execute($stid2);
}
Instead of inserting the expected value from the three $POST references (text only), three numbers are inserted into the table (numbers 1,2 and 3). I'm guessing that this is occurring because $comment can't be found, and uses $i instead for the value. In other words, it's not processing the variable name as I had hoped.
How can I configure the variable name in my INSERT statement so that it recognizes my variable names as "$comment_1", "$comment_2" and "$comment_3"? Do I need to use different quotes, or escape something?
$comment_$i in your code is not the correct way of initializing a variable that's why it shows wrong value. This should do the trick. Dynamic variable generation is the term used for this.
for($i=1;$i<=4;$i++) {
$variable = ${"comment_" . $i};
$sql2 = "INSERT INTO i_avail(IA_COMMENTS) VALUES('$variable')";
}
Use bind variables for security (to avoid SQL injection attacks) and for performance and scalability.
Also don't commit more than necessary.
Try:
$numvalues = 4;
$comment_1 = "A_comment";
$comment_2 = "B_comment";
$comment_3 = "C_comment";
$comment_4 = "D_comment";
$sql = "INSERT INTO i_avail (ia_comments) VALUES(:bv)";
$s = oci_parse($c, $sql);
if (!$s) {
$m = oci_error($c);
trigger_error('Could not parse statement: '. $m['message'], E_USER_ERROR);
}
for ($i=1; $i<=$numvalues; $i++) {
$variable = ${"comment_" . $i};
$r = oci_bind_by_name($s, ':bv', $variable);
if (!$r) {
$m = oci_error($s);
trigger_error('Could not bind a parameter: '. $m['message'], E_USER_ERROR);
}
// Only commit once after all data has been inserted
$commitmode = $i == $numvalues ? OCI_COMMIT_ON_SUCCESS : OCI_NO_AUTO_COMMIT;
$r = oci_execute($s, $commitmode);
if (!$r) {
$m = oci_error($s);
trigger_error('Could not execute statement: '. $m['message'], E_USER_ERROR);
}
}

MySQL query fails to execute

I am trying to query large amounts of data to a server, here is my code for that:
$queryString = "";
$connect = mysqli_connect("localhost", "username", "password", "database");
$loopLength = 20;
$currentGroup = 1;
$currentLoopAmount = 0;
$queryAmount = 5;
for($v = 0; $v < ceil($loopLength / $queryAmount); $v++){
//echo "Looping Main: " . $v . "<br>";
//echo $loopLength - (($currentGroup - 1) * 10) . "<br>";
if($loopLength - (($currentGroup - 1) * $queryAmount) >= $queryAmount){
$currentLoopAmount = $queryAmount;
}
else{
$currentLoopAmount = $loopLength - (($currentGroup - 1) * $queryAmount);
}
//echo $currentLoopAmount;
$queryString = "";
for($q = (($currentGroup - 1) * $queryAmount); $q < $currentLoopAmount + (($currentGroup - 1) * $queryAmount); $q++){
//echo " Looping Sub: " . $q . "<br>";
$tempVariable = grabPageData($URLs[$q], $q);
$queryString .= $tempVariable;
if($q < $loopLength-1){
$queryString .= ",";
}
else{
$queryString .= ";";
}
}
echo $queryString;
$query = "INSERT INTO PublicNoticesTable (url, county, paperco, date, notice, id) VALUES " . $queryString;
$result = mysqli_query($connect, $query);
if($result){
echo "Success";
}
else{
echo "Failed : " . mysqli_error($connect) . "<br>";
}
$currentGroup += 1;
}
The $loopLength variable is dynamic and can be in the thousands or potentially hundred thousands. I designed this function to divide that massive number into a batch of smaller queries as I couldn't upload all the data at one time on my shared hosting service through GoDaddy. The $queryAmount variable represents how big the smaller queries are.
Here is an example of one of the value sets that gets inserted into the table:
It is the data from a public notice that my code retrieved in the grabPageData() function.
('http://www.publicnoticeads.com/az/search/view.asp?T=PN&id=37/7292017_24266919.htm','Pima','Green Valley News and Sun','2017/07/30',' ___________________________ARIZONA SUPERIOR COURT, PIMA COUNTYIn the Matter of the Estate of:JOSEPH T, DILLARD, SR.,Deceased.DOB: 10/09/1931No. PB20170865NOTICE TO CREDITORS(FOR PUBLICATION)NOTICE IS HEREBY GIVEN that DANA ANN DILLARD CALL has been appointed Personal Representative of this Estate. All persons having claims against the Estate are required to present their claimswithin four months after the date of the firat publication of this notice or the claims will be forever barred. Claims must be presented by delivering or mailing a written statement of the claim to the Personal Representative at the Law Offices of Michael W. Murray, 257 North Stone Avenue, Tucson, Arizona 85701.DATED this 17th day of July, 2017./S/ Micahel W. MurrayAttorney for the Personal RepresentativePub: Green Valley News & SunDate: July 23, 30, August 6, 2017 Public Notice ID: 24266919',' 24266919'),
To attain this data, I run it through a function that crawls the page and grabs it. Then I put the webpage html code through this function:
function cleanData($data){
$data = strip_tags($data);
//$data = preg_replace("/[^a-zA-Z0-9]/", "", $data);
//$data = mysql_real_escape_string($data);
return $data;
}
Which gives me the content without tags as you see above. Here's the problem.
The function executes and everything seems just dandy. Then the function (depending on the $queryAmount variable which I don't keep over 10 for problem's sake) outputs, as you can see it would in the function something like...
Failed : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
The weird part is that when I have large amounts of data like say the $loopLength variable is like 116. The result will output, "Failed : (error)Failed : (Error)Fai...(Error)Success. So it's only actually querying the last set of data??? Not sure.
I am not sure how to fix this and I want a fresh eye. Can somebody help me please. I have been working on this problem for... several hours trying to find solution.
Sorry for making this question a pain in the butt :(
EDIT:
I changed the code from previously to use mysql prepared statements and what not... See below:
$grabDataResults = [
"url" => "",
"county" => "",
"paperco" => "",
"date" => "",
"notice" => "",
"id" => "",
];
$connect = mysqli_connect("localhost", "bwt_admin", "Thebeast1398", "NewCoDatabase");
if($stmt = mysqli_prepare($connect, "INSERT INTO PublicNoticesTable (url, county, paperco, date, notice, id) VALUES (?, ?, ?, ?, ?, ?)")){
mysqli_stmt_bind_param($stmt, 'ssssss', $grabDataResults["url"], $grabDataResults["county"], $grabDataResults["paperco"], $grabDataResults["date"], $grabDataResults["notice"], $grabDataResults["id"]);
$loopLength = 1;
for($v = 0; $v < $loopLength; $v++){
$grabDataResults = grabPageData($URLs[$v], $v);
mysqli_stmt_execute($stmt);
printf("%d Row inserted.\n", mysqli_stmt_affected_rows($stmt));
printf("Error:\n", mysqli_stmt_error($stmt));
echo "(" . $grabDataResults["url"] . "," . $grabDataResults["county"] . "," . $grabDataResults["paperco"] . "," . $grabDataResults["date"] . "," . $grabDataResults["notice"] . "," . $grabDataResults["id"] . ")";
}
mysqli_stmt_close($stmt);
mysqli_close($connect);
}
Unfortunately this is what I get from the output:
1 Row inserted. 0 Error:
No error actually prints out and the row is inserted. However when I navigate to my database, and look at the values that have been stored.. They are all empty. The echo statement outputs this:
(http://www.publicnoticeads.com/az/search/view.asp?T=PN&id=31/7292017_24266963.htm,Yuma,Sun (Yuma), The,2017/07/30,, 24266963)
So I know that all of the variables contain something except for the $notice variable which gets destroyed by my cleanData() function for some reason.
You need to bind the data after fetching it and before executing it...
$loopLength = 1;
for($v = 0; $v < $loopLength; $v++){
$grabDataResults = grabPageData($URLs[$v], $v);
mysqli_stmt_bind_param($stmt, 'ssssss', $grabDataResults["url"],
$grabDataResults["county"], $grabDataResults["paperco"],
$grabDataResults["date"], $grabDataResults["notice"],
$grabDataResults["id"]);
mysqli_stmt_execute($stmt);
printf("%d Row inserted.\n", mysqli_stmt_affected_rows($stmt));
printf("Error:\n", mysqli_stmt_error($stmt));
echo "(" . $grabDataResults["url"] . "," . $grabDataResults["county"] . "," . $grabDataResults["paperco"] . "," . $grabDataResults["date"] . "," . $grabDataResults["notice"] . "," . $grabDataResults["id"] . ")";
}
You code is correct. Just you need to add () arround querystring
Akso you need to remove ; from query string end. SO remove following else condition
else{
$queryString .= ";";
}
change you query like :
$query = "INSERT INTO PublicNoticesTable (url, county, paperco, date, notice, id) VALUES (" . $queryString . ")";
Also it advisable to use prepared statements to prevent from sql injections
The main error I can see on your query, are the query itself. You're using a INSERT INTO with separated fields and values. But you forget to use the pharentesis on values.
Remember, the use of INSERT INTO are as follows:
First option:
INSERT INTO table field1 = value1, field2 = value2;
Second option:
INSERT INTO table (field1, field2) VALUES (value1, value2);
Also, remember to escape every field and value for avoid more errors: Example:
First option:
INSERT INTO `table` `field1` = 'value1', `field2` = 'value2';
Second option:
INSERT INTO `table` (`field1`, `field2`) VALUES ('value1', 'value2');
If you're using mysqli driver, for more security, you can use prepared statements, to get your values automatically escaped. In that case, the syntax of the query are as follows:
First option:
INSERT INTO `table` `field1` = ?, `field2` = ?;
Second option:
INSERT INTO `table` (`field1`, `field2`) VALUES (?, ?);
Also, instead of using mysqli_query(), you need to use mysqli_prepare(), mysqli_bind_param() and mysqli_execute(). You can check more data about they syntax here: http://php.net/manual/en/mysqli.prepare.php
At least, you can use mysqli_real_escape_string() function for getting your input properly escaped and checked. You can check documentation of this function here: http://php.net/manual/en/mysqli.real-escape-string.php

PHP Warning: sprintf(): Too few arguments in

I have a cronjob which runs a script -> getting data from different itunes stores. Sometimes i get the above mentioned error message.
I think its because of special letters or something like this. Is there a way to check, where the problem exactly is? Which "special character" is respsonisble for the error. Is there a workaround for example with a IF statement?
I canĀ“t reproduce the error, as it not appears always. Would be great to get help on this.
Here is the code:
foreach ($Kategorien->entry as $item) {
$id = addslashes($item->id);
$title = utf8_decode(addslashes($item->title));
$preview = addslashes($item->link[1]["href"]);
$namespaces = $item->getNameSpaces(true);
$im = $item->children($namespaces['im']);
$track_title = utf8_decode(addslashes($im->name));
$track_artist = utf8_decode(addslashes($im->artist));
$track_amount = addslashes($im->price->attributes()->amount);
$track_currency = utf8_decode(addslashes($im->price->attributes()->currency));
$release_date = addslashes($im->releaseDate);
$image = addslashes($im->image[2]);
$entry_id['im'] = $item->id->attributes('im', TRUE);
$track_id = addslashes($entry_id['im']['id']);
$category_id['im'] = $item->category->attributes('im', TRUE);
$genre_id = addslashes($category_id['im']['id']);
$genre_cat = utf8_decode(addslashes($item->category->attributes()->term));
$insertSQL = sprintf("UPDATE track_itunes_countries_total SET modified = NOW(), modified_genre = '$genre_name' WHERE id = ".$row_select_country['id']."");
$Result1 = mysql_query($insertSQL, $con) or die(mysql_error());
$insertSQL = sprintf("INSERT INTO track_itunes_".$cc."_total (id, title, preview, track_title, track_artist, track_amount, track_currency, release_date, image, track_id, genre_id, genre_cat, country, Online, Approved) VALUES ('$id', '$title', '$preview', '$track_title', '$track_artist', '$track_amount', '$track_currency', '$release_date', '$image', '$track_id', '$genre_id', '$genre_cat', '$cc', '1', '1') ON DUPLICATE KEY UPDATE title='$title',preview='$preview',track_title='$track_title',track_artist='$track_artist',track_amount='$track_amount',track_currency='$track_currency',release_date='$release_date',image='$image',track_id='$track_id',genre_id='$genre_id',genre_cat='$genre_cat',country='$cc'");
$Result1 = mysql_query($insertSQL, $con);}
I will answer in a tangential way, because you're using mysql_* library which is deprecated and show you PDO instead. This will either a) solve your problem or b) provide a much more informative error message that will help you debugging.
foreach ($Kategorien->entry as $item) {
$id = $item->id;
$title = utf8_decode($item->title);
$preview = $item->link[1]["href"];
$namespaces = $item->getNameSpaces(true);
$im = $item->children($namespaces['im']);
$track_title = utf8_decode($im->name);
$track_artist = utf8_decode($im->artist);
$track_amount = $im->price->attributes()->amount;
$track_currency = utf8_decode($im->price->attributes()->currency);
$release_date = $im->releaseDate;
$image = $im->image[2];
$entry_id['im'] = $item->id->attributes('im', TRUE);
$track_id = $entry_id['im']['id'];
$category_id['im'] = $item->category->attributes('im', TRUE);
$genre_id = $category_id['im']['id'];
$genre_cat = utf8_decode($item->category->attributes()->term);
$insertSQL = "UPDATE track_itunes_countries_total
SET modified = NOW(), modified_genre = :genre_name
WHERE id = :row_id");
$stmt = $pdo->prepare($insertSQL);
$stmt->bindValue(':genre_name', $genre_name);
$stmt->bindValue(':row_id', $row_select_country['id']);
$success = $stmt->execute();
if(!$success){
//something bad happened
}
//use whitelist techniques to guarantee valid, non-malicious input
//with table names or column names. whitelistTableName is a function
//that YOU have to write.
$clean_table_name = whitelistTableName("track_itunes_{$cc}_total");
$insertSQL = "INSERT INTO {$clean_table_name}
(id, title, preview, track_title,
track_artist, track_amount, track_currency,
release_date, image, track_id, genre_id,
genre_cat, country, Online, Approved)
VALUES
(:id, :title, :preview, :track_title,
:track_artist, :track_amount, :track_currency,
:release_date, :image, :track_id, :genre_id,
:genre_cat, :country, :Online, :Approved)
ON DUPLICATE KEY UPDATE
title=:title_u,preview=:preview_u,track_title=:track_title_u,
track_artist=:track_artist_u,track_amount=:track_amount_u,
track_currency=:track_currency_u,release_date=:release_date_u,
image=:image_u,track_id=:track_id_u,genre_id=:genre_id_u,
genre_cat=:genre_cat_u,country=:cc_u");
$stmt = $pdo->prepare($insertSQL);
$stmt->bindValue(':id', $id);
$stmt->bindValue(':title', $title);
$stmt->bindValue(':preview', $preview);
$stmt->bindValue(':track_title', $track_title);
$stmt->bindValue(':track_artist', $track_artist);
$stmt->bindValue(':track_amount', $track_amount);
$stmt->bindValue(':track_currency', $track_currency);
$stmt->bindValue(':release_date', $release_date);
$stmt->bindValue(':image', $image);
$stmt->bindValue(':track_id', $track_id);
$stmt->bindValue(':genre_id', $genre_id);
$stmt->bindValue(':genre_cat', $genre_cat);
$stmt->bindValue(':country', $cc);
$stmt->bindValue(':Online', 1);
$stmt->bindValue(':Approved', 1);
//some drivers doesn't allow to have a named placeholder to appear more than once so we must duplicate those.
$stmt->bindValue(':id_u', $id);
$stmt->bindValue(':title_u', $title);
$stmt->bindValue(':preview_u', $preview);
$stmt->bindValue(':track_title_u', $track_title);
$stmt->bindValue(':track_artist_u', $track_artist);
$stmt->bindValue(':track_amount_u', $track_amount);
$stmt->bindValue(':track_currency_u', $track_currency);
$stmt->bindValue(':release_date_u', $release_date);
$stmt->bindValue(':image_u', $image);
$stmt->bindValue(':track_id_u', $track_id);
$stmt->bindValue(':genre_id_u', $genre_id);
$stmt->bindValue(':genre_cat_u', $genre_cat);
$stmt->bindValue(':country_u', $cc);
$stmt->bindValue(':Online_u', 1);
$stmt->bindValue(':Approved_u', 1);
$success = $stmt->execute();
if(!$success){
//something bad happened
}
}
more to read here: http://php.net/manual/en/book.pdo.php It's pretty easy and much better than mysql_* libraries
Expanding on the whitelisting techniques: there are several approaches to sanitize user inputs. One is escaping: this is done where the user input is "open ended" like a text input, where there is an unlimited number of possibilities. Prepared statements are perfect for this, as demonstrated above.
Another possibility is whitelisting, and it's useful when there are only limited valid possibilities for the user input (for example, radiobuttons, checkboxes, option selections, etc.) and any invalid input is either an error or malicious.
an example follows:
whitelistTableName($tablename){
$allowedTables = array('tbl1', 'tbl2', 'tbl3');
if(in_array($tablename, $allowedTables)){
return $tablename;
} else {
throw new Exception('Malicious attempt detected');
}
}
This is very basic but allows you to get started. A better approach would be to query your information_schema database to fetch every valid table name rather than hardcoding them by hand.
That's not how sprintf works.
sprintf means string printf -- you are doing a printf which returns a string instead of printing directly into stdout.
printf works by assigning placeholders into a format string (the first argument), and the bound values to the placeholders as the succeeding arguments.
for example
$s = sprintf("SELECT * FROM %s WHERE id = %d", 'some_table', $id);
This is in some way a naive way to sanitize input since you are forcing variables to be cast into certain types using the formats: in this case %s and %d for string and decimal/digit, respectively. At runtime, these will be replaced by "some_table", and whatever intval($id) is.
The reason you are getting "Too few arguments" is because you are missing the bound values.
First of all: you should use mysql_real_escape_string() or even better use mysqli instead of mysql functions since mysql is deprecated.
And for the errormessage you should have a look into the documentation of sprintf to understand the error.
Or just use proper concatination.
$string = "fooo='".$var."'";
instead of your lazy notation
$string = "fooo='$var'";
Here is an example including mysql_real_escape_string():
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
mysql_real_escape_string($user),
mysql_real_escape_string($password));
You can also give specific positions for the bound vars:
$query = sprintf("SELECT * FROM users WHERE user='%2$s' AND password='%1$s'",
mysql_real_escape_string($password),
mysql_real_escape_string($user)
);
And for the mysql_query(), you don't need to supply the connection link $con if you don't use more then 1 database connection.
mysql_query($query);
will do the trick.

How to insert data into MySql using an associative array [duplicate]

This question already has an answer here:
Mysqli prepared statements build INSERT query dynamically from array
(1 answer)
Closed 8 months ago.
I am now having a problem inserting data in associative array with its key as fields in the table and the values to be inserted into MySql database. Here is my code.
<?php
$table = 'articles';
$data = array(
'title' => 'Header',
'content' => 'This is content',
'author' => 'James');
$keys = implode(', ', array_keys($data));
$values = implode(', ', array_values($data));
$sql = 'insert into '.$table.'('.$keys.') values ('.$values.')';
$db = new mysqli('localhost', 'root', 'root', 'blog');
$db->query($sql);
?>
With this code, I wasn't able to insert the data into the database so I try to echo the query string out and I got something like this :
insert into articles(title, content, author) values (Header, This is content, James)
However, if I use the single quote in each value like this
insert into articles(title, content, author) values ('Header', 'This is content', 'James')
I can successfully insert the data into the database.
So I don't know what's wrong here. Is it a problem with the quote sign or not because when I use the single quote, this seems to work.
So please help me find the proper solution for this...
For the query you need to enclose each value in quotes. To do that you can change your implode statement to include the quotes to around the values -
$values = "'" .implode("','", array_values($data)) . "'";
EXAMPLE-demo
You should also be checking for errors.
Replace $db->query($sql);
with
if(!$result = $db->query($sql)){
die('There was an error running the query [' . $db->error . ']');
}
else{
echo "Data inserted.";
}
So I don't know what's wrong here. Is it a problem with the quote sign or not because when I use the single quote, this seems to work.
Yes, you need to use the single quote.
You can check it out:
$values = implode(', ', array_values($data));
Into something like it:
$values = implode (',', array_map (
function ($z)
{
return ((is_numeric ($z) || (is_string ($z) ? ($z == "NOW()" ? true : false) : false) || (is_array ($z)?(($z=implode(";",$z))?false:false):false)) ? $z : "'" . utf8_decode ($z) . "'");
}, array_values ($data)));
The idea is that you make every value field quoted, I meant value field by value field in the query. For instance, in my example, the function ignores NOW() as string, and keep it up to work as SQL's timestamp. Because if you treat it as string type, the command wouldn't work properly.
Anyway, the above is ugly and insecure.
I would advice you to look for some ORM like RedBeanORM or, maybe, use the proper PHP MySQL version like MySQLi. Mainly to avoid SQL injections.
Look one ORM example:
require 'rb.php';
R::setup();
$post = R::dispense('post');
$post->text = 'Hello World';
$id = R::store($post); //Create or Update
$post = R::load('post',$id); //Retrieve
R::trash($post); //Delete
Look one PHP MySQL improved version example:
$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent);
$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;
mysqli_stmt_execute($stmt);
Good luck. Good learning.
Positional place-holders:
$values = implode(', ',
array_fill(0, count($data), '?')
);
// insert into articles(title, content, author) values (?, ?, ?)
Named place-holders:
$values = implode(', ', array_map(
function($value){
return ":$value";
},
array_keys($data)
));
// insert into articles(title, content, author) values (:title, :content, :author)
Not necessarily the nicest or best code.
As about the parameter array itself, I'm not familiar with mysqli but with many DB extensions you could use $data as-is.

Inserting multiple rows in a table using PHP

I am trying to insert multiple rows into MySQL DB using PHP and HTML from. I know basic PHP and searched many examples on different forums and created one script however it doesn't seem working. Can anybody help with this. Here is my script:
include_once 'include.php';
foreach($_POST['vsr'] as $row=>$vsr) {
$vsr=mysql_real_escape_string($vsr);
$ofice=mysql_real_escape_string($_POST['ofice'][$row]);
$date=mysql_real_escape_string($_POST['date'][$row]);
$type=mysql_real_escape_string($_POST['type'][$row]);
$qty=mysql_real_escape_string($_POST['qty'][$row]);
$uprice=mysql_real_escape_string($_POST['uprice'][$row]);
$tprice=mysql_real_escape_string($_POST['tprice'][$row]);
}
$sql .= "INSERT INTO maint_track (`vsr`, `ofice`, `date`, `type`, `qty`, `uprice`,
`tprice`) VALUES ('$vsr','$ofice','$date','$type','$qty','$uprice','$tprice')";
$result = mysql_query($sql, $con);
if (!$result) {
die('Error: ' . mysql_error());
} else {
echo "$row record added";
}
MySQL can insert multiple rows in a single query. I left your code as close as possible to the original. Keep in mind that if you have a lot of data, this could create a large query that could be larger than what MySQL will accept.
include_once 'include.php';
$parts = array();
foreach($_POST['vsr'] as $row=>$vsr) {
$vsr=mysql_real_escape_string($vsr);
$ofice=mysql_real_escape_string($_POST['ofice'][$row]);
$date=mysql_real_escape_string($_POST['date'][$row]);
$type=mysql_real_escape_string($_POST['type'][$row]);
$qty=mysql_real_escape_string($_POST['qty'][$row]);
$uprice=mysql_real_escape_string($_POST['uprice'][$row]);
$tprice=mysql_real_escape_string($_POST['tprice'][$row]);
$parts[] = "('$vsr','$ofice','$date','$type','$qty','$uprice','$tprice')";
}
$sql = "INSERT INTO maint_track (`vsr`, `ofice`, `date`, `type`, `qty`, `uprice`,
`tprice`) VALUES " . implode(', ', $parts);
$result = mysql_query($sql, $con);
Please try this code. Mysql query will not accept multiple insert using php. Since its is a for loop and the values are dynamically changing you can include the sql insert query inside the for each loop. It will insert each rows with the dynamic values. Please check the below code and let me know if you have any concerns
include_once 'include.php';
foreach($_POST['vsr'] as $row=>$vsr) {
$vsr=mysql_real_escape_string($vsr);
$ofice=mysql_real_escape_string($_POST['ofice'][$row]);
$date=mysql_real_escape_string($_POST['date'][$row]);
$type=mysql_real_escape_string($_POST['type'][$row]);
$qty=mysql_real_escape_string($_POST['qty'][$row]);
$uprice=mysql_real_escape_string($_POST['uprice'][$row]);
$tprice=mysql_real_escape_string($_POST['tprice'][$row]);
$sql = "INSERT INTO maint_track (`vsr`, `ofice`, `date`, `type`, `qty`, `uprice`,
`tprice`) VALUES ('$vsr','$ofice','$date','$type','$qty','$uprice','$tprice')";
$result = mysql_query($sql, $con);
if (!$result)
{
die('Error: ' . mysql_error());
}
else
{
echo "$row record added";
}
}
I would prefer a more modern approach that creates one prepared statement and binds parameters, then executes within a loop. This provides stable/secure insert queries and avoids making so many escaping calls.
Code:
// switch procedural connection to object-oriented syntax
$stmt = $con->prepare('INSERT INTO maint_track (`vsr`,`ofice`,`date`,`type`,`qty`,`uprice`,`tprice`)
VALUES (?,?,?,?,?,?,?)'); // use ?s as placeholders to declare where the values will be inserted into the query
$stmt->bind_param("sssssss", $vsr, $ofice, $date, $type, $qty, $uprice, $tprice); // assign the value types and variable names to be used when looping
foreach ($_POST['vsr'] as $rowIndex => $vsr) {
/*
If you want to conditionally abort/disqualify a row...
if (true) {
continue;
}
*/
$ofice = $_POST['ofice'][$rowIndex];
$date = $_POST['date'][$rowIndex];
$type = $_POST['type'][$rowIndex];
$qty = $_POST['qty'][$rowIndex];
$uprice = $_POST['uprice'][$rowIndex];
$tprice = $_POST['tprice'][$rowIndex];
echo "<div>Row# {$rowIndex} " . ($stmt->execute() ? 'added' : 'failed') . "</div>";
}
To deny the insertion of a row, use the conditional continue that is commented in my snippet -- of course, write your logic where true is (anywhere before the execute call inside the loop will work).
To adjust submitted values, overwrite the iterated variables (e.g. $vsr, $ofice, etc) before the execute call.
If you'd like to enjoy greater data type specificity, you can replace s (string) with i (integer) or d (double/float) as required.

Categories