I have a loop in which I have to do multiple inserts to the database, it appears that I have to bind the data array every time I get new data and the data changes. I though we could bind once and insert multiple times.
Further research has shown that PDO might be better suited to this task, but I'm curious why its like this with mysqli, and if there is a way to bind array once and execute multiple times.
See comments in code for more detail.
<?php
//usual db stuff
$DBhost = 'localhost';
$DBname = 'test';
$DBuser = '';
$DBpass = '';
//error reporting for mysql
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
//connect to database
$conn = new mysqli($DBhost, $DBuser, $DBpass, $DBname);
//prepare this is a dummy table in a dummy database
//actual table is quite complicated
$stmt = $conn->prepare('INSERT INTO `users` (`fname`,`lname`,`city`) VALUES(?,?,?)');
//create a variable to store the data
// so we can bind it before going further
$data=array_fill(0,3,'');
//bind params use array expansion
$stmt->bind_param('sss', ...$data);
//this part runs in a loop
// mock loop for just to show idea
for($i=0;$i<1;$i++)
{
//get the data
$data = get_data();
//already binded $data before the loop
//so execute this should insert the data just returned
//except this doesnt, it inserts blanks
//it acts as if the data still has the blank array from line 20
$stmt->execute();
//bind it again
$stmt->bind_param('sss', ...$data);
//execute
//this inserts the data
$stmt->execute();
}
//mock function to return data the actual function
//returns a multi dimesional array for multiple tables
function get_data()
{
return(array("dinesh","chand","nadi"));
}
any help or ideas highly appreciated
When you run $stmt->execute(); for the first time, inside the for loop, you are executing what you have bind before starting the for loop. So what you have to do is.
Bind what you want $stmt->bind_param('sss', ...$data);
Then execute $stmt->execute();
In your code above, first, remove $stmt->execute(); (first inside the for loop). Then add it after you bind the parameters for the first time(above the for loop). As follows,
Note: What I have changed are marked with ########
<?php
//usual db stuff
$DBhost = 'localhost';
$DBname = 'test';
$DBuser = '';
$DBpass = '';
//error reporting for mysql
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
//connect to database
$conn = new mysqli($DBhost, $DBuser, $DBpass, $DBname);
//prepare this is a dummy table in a dummy database
//actual table is quite complicated
$stmt = $conn->prepare('INSERT INTO `users` (`fname`,`lname`,`city`) VALUES(?,?,?)');
//create a variable to store the data
// so we can bind it before going further
$data=array_fill(0,3,'');
//bind params use array expansion
$stmt->bind_param('sss', ...$data);
$stmt->execute(); //########
//this part runs in a loop
// mock loop for just to show idea
for($i=0;$i<1;$i++)
{
//get the data
$data = get_data();
//already binded $data before the loop
//so execute this should insert the data just returned
//except this doesnt, it inserts blanks
//it acts as if the data still has the blank array from line 20
//$stmt->execute(); ########
//bind it again
$stmt->bind_param('sss', ...$data);
//execute
//this inserts the data
$stmt->execute();
}
Related
MySQL is not using the variables as it should. it is not taking any value from them it is incrementing the auto-increment numbers in the MYSQL table, however the row is not saved. I am not given any errors.
I have tried like this:
$sql = "INSERT INTO `tbl_bike` (`userID`, `ManuPartNo`, `BikeManufacturer`, `BikeModel`, `BikeType`, `BikeWheel`, `BikeColour`, `BikeSpeed`, `BrakeType`, `FrameGender`, `AgeGroup`, `DistFeatures`)
VALUES (“.$userID.”, “.$PartNo.”, “.$BikeManufacturer.”, “.$BikeModel.”, “.$BikeType.”, “.$BikeWheel.”, “.$BikeColour.”, “.$BikeSpeed.”, “.$BrakeType.”, “.$FrameGender.”, “.$AgeGroup.”, “.$DistFeatures.”)";
I have also tried replacing the " with ', Removing the . and even completely removing the ". Nothing has helped with this issue. When I use this query but remove the variables and instead put string, int etc in the correct places the query will function perfectly and put the results into the table. My variables are normally as follows:
$PartNo = $_POST['ManuPartNo’];
$BikeManufacturer = $_POST['BikeManufacturer’];
$BikeModel = $_POST['BikeModel’];
$BikeType = $_POST['BikeType’];
$BikeWheel = $_POST['BikeWheel’];
$BikeColour = $_POST['BikeColour’];
$BikeSpeed = $_POST['BikeSpeed’];
$BrakeType = $_POST['BrakeType’];
$FrameGender = $_POST['FrameGender’];
$AgeGroup = $_POST['AgeGroup’];
$DistFeatures = $_POST['DistFeatures’];
These variables normally take input from a separate PHP/HTML file with the '$_POST['DistFeatures’];'
I have tried removing the $_POST['DistFeatures’]; from the ends of each of them and just replacing the values with normal string or int values but still nothing helps. I am completely stuck and would appreciate any help with this.
This is all running on a plesk server.
Please stop using deprecated MySQL. I will suggest an answer using PDO. You can use this to frame your other queries using PDO.
// Establish a connection in db.php (or your connection file)
$dbname = "dbname"; // your database name
$username = "root"; // your database username
$password = ""; // your database password or leave blank if none
$dbhost = "localhost";
$dbport = "10832";
$dsn = "mysql:dbname=$dbname;host=$dbhost";
$pdo = new PDO($dsn, $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
// Include db.php on every page where queries are executed and perform queries the following way
// Take Inputs this way (your method is obsolete and will return "Undefined Index" error)
$userId = (!empty($_SESSION['sessionname']))?$_SESSION['sessionname']:null; // If session is empty it will be set to Null else the session value will be set
$PartNo = (!empty($_POST['ManuPartNo']))?$_POST['ManuPartNo']:null; // If post value is empty it will be set to Null else the posted value will be set
$BikeManufacturer = (!empty($_POST['BikeManufacturer']))?$_POST['BikeManufacturer']:null;
$BikeModel = (!empty($_POST['BikeModel']))?$_POST['BikeModel']:null;
$BikeType = (!empty($_POST['BikeType']))?$_POST['BikeType']:null;
$BikeWheel = (!empty($_POST['BikeWheel']))?$_POST['BikeWheel']:null;
// Query like this
$stmt = $pdo->prepare("INSERT INTO(`userID`, `ManuPartNo`, `BikeManufacturer`, `BikeModel`, `BikeType`)VALUES(:uid, :manuptno, :bkman, :bkmodel, :bktype)");
$stmt-> bindValue(':uid', $userId);
$stmt-> bindValue(':manuptno', $PartNo);
$stmt-> bindValue(':bkman', $BikeManufacturer);
$stmt-> bindValue(':bkmodel', $BikeModel);
$stmt-> bindValue(':bktype', $BikeType);
$stmt-> execute();
if($stmt){
echo "Row inserted";
}else{
echo "Error!";
}
See, it's that simple. Use PDO from now on. It's more secured. To try this, just copy the whole code in a blank PHP file and and run it. Your database will receive an entry. Make sure to change your database values here.
You should try this
$sql = "INSERT INTO tbl_bike (userID, ManuPartNo, BikeManufacturer, BikeModel, BikeType, BikeWheel, BikeColour, BikeSpeed, BrakeType, FrameGender, AgeGroup, DistFeatures) VALUES ('$userID', '$PartNo', '$BikeManufacturer', '$BikeModel', '$BikeType', '$BikeWheel', '$BikeColour', '$BikeSpeed', '$BrakeType', '$FrameGender', '$AgeGroup', '$DistFeatures')";
If this doesn't work, enable the null property in sql values. So you can find out where the error originated.
I've tried to debug this times without success. Here is what I've tried so far
<?php
$cid= (string)$_GET['cid'];//I passed this from another page using get method
echo $cid; //My code works up to this point
$record = mysql_query("select * from questions where QType = '$cid'");
$array = array();
while($row = mysql_fetch_assoc($record))
{
$array[] = $row;
}
for($var = 0; $var<count($array);$var++)
{
echo $array[$var]['Question'].'<br>';
}
?>
This code will work and is a bit safer
<?php
//Connection part
$servername = "server_adress"; //It can be localhost or 127.0.0.1 or some other IP
$username = "XXXXXX"; //Username for DB
$password = "YYYYYY"; //Password for that user
$database = "ZZZZZZ"; //DB name you are connecting to
//Create a new connection
$conn_to_db = new mysqli($servername, $username, $password,$database);
// Check connection
if ($conn_to_db -> connect_error) {
die("Connection failed: " . $conn_to_db ->connect_error);
}
//Finished connection part
$cid = mysqli_real_escape_string($conn_to_db, $_GET['cid']); //Escapes special characters in a string for use in an SQL statement
$array = array();
if($stmt = $conn_to_db -> ("SELECT * FROM questions WHERE QType = ?")) {
$stmt -> bind_param("s", $cid);
$stmt -> execute();
$stmt -> bind_result($question_from_db); //Here you can put all variables you are fetching from DB
while($stmt -> fetch()){
//Iterate over rows - put your code here to fetch everything you need from DB and put in array
$array[] = array('question' => $question_from_db);
}
$stmt -> close();
}
}
//you can iterate over rows like this
foreach($array as $key => $value) {
echo $value['question'];
}
?>
Couple of things to keep in mind:
it's a good practice to avoid * (selecting everything from DB) and
put only columns you need from DB
use prepared statement which is a safer way and protects you from SQL injection
MySQL is depreciated so try to avoid it (use mysqli or PDO)
The code above you need to adjust to your needs! It will not work as copy/paste. Put your DB connection and select columns from DB you need and add variables which you fetch from DB
Keep in mind there are more ways to do this, and someone will probably give another solution.
if you are not on a production server, it's good to have some error reporting to see the errors that are happening
I wrote the following code to retrieve data from the database
<?php
$host = 'localhost';
$username = 'root';
$password = '';
$database = 'users';
$con = mysqli_connect($host, $username, $password, $database);
// catch the values that are passed by the POST method
$courseId=$_POST["courseId"];
$hall=$_POST["hall"];
$day=$_POST["day"];
$year=$_POST["year"];
$time=$_POST["time"];
$statement=mysqli_prepare($con,"SELECT * FROM Lectures WHERE day=? AND timeInterval=? AND courseId=? AND hall=? AND year=? ");
mysqli_stmt_bind_param($statement,"sssss",$courseId,$hall,$day,$year,$time);
mysqli_stmt_execute($statement);
// have to collect the results that are coming after the query is being executed
mysqli_stmt_store_result($statement); //storing the results in a buffer for temporary
// now we need to bind the results
mysqli_stmt_bind_result($statement,$day,$time,$courseId,$hall,$year,$noStudents,$courseRefName,$courseRefTelNo,$lecturer);
// to send the data via JSON string
$lectureDetails=array();
mysqli_stmt_fetch($statement);
$lectureDetails["day"]=$day;
$lectureDetails["time"]=$time;
$lectureDetails["courseId"]=$courseId;
$lectureDetails["hall"]=$hall;
$lectureDetails["year"]=$year;
$lectureDetails["noStudents"]=$noStudents;
$lectureDetails["courseRefName"]=$courseRefName;
$lectureDetails["courseRefTelNo"]=$courseRefTelNo;
$lectureDetails["lecturer"]=$lecturer;
// data are stored in the array. now we need to send them via a JSON string
echo json_encode($lectureDetails);
// the java file that calls this method will receive echo
//The PHP json_encode function returns a string, containing the JSON equivalent of the values passed to it
//so in here $lectureDetails array is passed throught throughe JSON String.
mysqli_stmt_close($statement); //closing the connection
mysqli_close($con); //closing the sql connection
?>
according to the working fetching file as below(this returns values as expected)
<?php
//database connection
$host = 'localhost';
$user1 = 'root';
$password1 = '';
$database = 'users';
$con = mysqli_connect($host, $user1, $password1, $database);
//checking the validity of the database
// if(!$con){
//die("connection Failed" . mysqli_connect_error());}
//echo "connected Successfully";
$userName=$_POST["userName"];
$password=$_POST["password"];
$statement=mysqli_prepare($con,"SELECT * FROM usersLogged WHERE userName=? AND password=?");
//to prevent from sql injection
mysqli_stmt_bind_param($statement,"ss",$userName,$password);
mysqli_stmt_execute($statement);
//after executing the command we will get all the results that were selected
mysqli_stmt_store_result($statement); //storing the results in a buffer for temporary
//we need to bind the results
mysqli_stmt_bind_result($statement, $userId, $userName, $firstName, $lastName, $password, $position,$birthDate,$qualification,$email);
//now we need to store them into an array inoder to send them via a JSON
$user=array();
mysqli_stmt_fetch($statement);
//fetch the result from a prepared statement into the variables bound by mysqli_stmt_bind_result.
//Data are transferred unbuffered without calling mysqli_stmt_store_result() which can decrease performance (but reduces memory cost).
//storing the values which are fetched from the database are kept in the array(#user)
$user["userName"]=$userName;
$user["firstName"]=$firstName;
$user["lastName"]=$lastName;
$user["password"]=$password;
$user["position"]=$position;
$user["birthDate"]=$birthDate;
$user["qualification"]=$qualification;
$user["email"]=$email;
//now we need to pass the content to the phone,we send the array in a json
echo json_encode($user); // the java file that calls this method will receive echo
//The PHP json_encode function returns a string, containing the JSON equivalent of the values passed to it
//so in here $user array is passed throught the JSON String.
mysqli_stmt_close($statement);
mysqli_close($con);
?>
but the above php file is not fetching data from the mysql database.
I have created a Lectures table at the current users database and day time courseId hall year courseRefName and lecuturer are of String data type , noStudents and courseRefTelNo are of integer datatype.
Is there any mistake in the mysqli_prepare or in the way this is encoded to JSON, because Iam not getting any return from this (above) php file to my java in android application
I found the problem, it was the mismatch between the data sent via POST and in the database had caused the problem. I have sent time in form of 08.00-10.00 and in database they were as 08-10 in form of 5 digits. So if anyone encounter problems like these be first check the data in the database and the values you passed through POST method
This question already has an answer here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Closed 2 years ago.
Having trouble with line 27, Don't quite know why as I am very new to PHP/MySQL.
Was wondering if anybody can advise me why I am getting the error;
"Fatal error: Call to a member function execute() on a non-object in
C:\xampp\htdocs\testscripts\usercreate.php on line 27"
in the following code:
<?php
$name = $_POST["name"];
$psswrd = $_POST["psswrd"];
$username = "root";
$password = "hidden";
$hostname = "localhost";
$table = "testtable";
// create connection to database
// ...
$db= new mysqli($hostname, $username, $password, $table);
// sanitize the inputs
// ...
// create an MD5 hash of the password
$psswrd = md5($psswrd);
// save the values to the database
$sql = "INSERT INTO accounts (name, psswrd) VALUES (:name, :psswrd)";
$stmt = $db->prepare($sql);
$stmt->execute(array(
":name" => $name,
":psswrd" => $psswrd
));
->prepare returns false if an error occurred. Since $stmt->execute is complaining of being called on a non-object, it's reasonable to assume that something went wrong with the query.
Check $db->error.
Try this :
$db= new mysqli($hostname, $username, $password, $table);
if ($db->connect_errno) {
throw new Exception($db->connect_error, $db->connect_errno);
}
$psswrd = md5($psswrd);
// save the values to the database
$sql = "INSERT INTO accounts (name, psswrd) VALUES (:name, :psswrd)";
$stmt = $db->prepare($sql);
if (!$stmt) {
throw new Exception($db->error);
}
$stmt->execute(array(
":name" => $name,
":psswrd" => $psswrd
));
Show your all exception for better idea of given error.
First thing, the fourth parameter the MySQLi class takes is the database name, not the table name.
So, change the$table = 'testtable'; to something like this : $dbname = 'dbname';
Also, in your code, you are using named parameters (:name and :passwrd). This won't work because MySQLi doesn't support named parameters. PDO (PHP Data Objects) supports named parameters. If you use the PDO class to connect to the database, your script will work fine!
If you want to connect to the database using the MySQLi class, do this :
$name = $_POST['name'];
$psswrd = $_POST['psswrd'];
$username = "root";
$password = "";
$hostname = "localhost";
$dbname = "dbname";
// create connection to database
// ...
$db= new mysqli($hostname, $username, $password, $dbname);
// sanitize the inputs
// ...
// create an MD5 hash of the password
$psswrd = md5($psswrd);
// save the values to the database
$sql = "INSERT INTO `testtable` (id, name) VALUES (?, ?)";
$stmt = $db->prepare($sql);
$stmt->bind_param('ss', $name, $psswrd);
$stmt->execute();
Try that. Use question marks instead of named parameters.
In the bind_param() function, I've written the first parameter as 'ss'. The two 's' here stands for Strings. If you had an integer data, you could have replaced 's' with 'i'.
It's pretty self explanatory as to why there are two 's'. It's because you are binding two variables to the SQL query, both of them are strings. Hence the two 's'.
The server is running PHP 5.2.8. PDO has mysql 5.1.30 drivers installed.
Alright, so I am trying to figure out some PDO ( and this is just killing me. When I run the code below, I get the expected results, no problem.
However, whenever I try to add more than one column (or *) to the SELECT, there is no reply from the query - no results whatsoever. I have tried everything - I know it must be something simple. Any suggestions as to why more than one column fails to return any rows?
$hostname = "localhost";
$dbname = "dbname";
$username = "username";
$password = "password";
try {
$dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
/*** echo a message saying we have connected ***/
echo 'Connected to database<br />';
/*** The SQL SELECT statement ***/
$sql = "SELECT LastName FROM staff";
foreach ($dbh->query($sql) as $row) {
echo $row['LastName'] . '<br />';
}
/*** close the database connection ***/
$dbh = null;
} catch(PDOException $e) {
echo $e->getMessage();
}
Again, if I try to add columns in the statement stored in $sql to anything other than a single column, I get bupkis. For example:
SELECT FirstName, LastName FROM staff
returns zero results. Both columns exist - if requested separately, they return expected results. When combined, the query takes quite some time, then returns nothing.
No exception is caught by the catch block.
I think you have a number of issues here, mostly in your code that handles reading the values returned by the query. I have taken the liberty of changing a few things and rewriting this to use prepare statements, which is a function that PDO provides that you should take advantage of.
On prepare statements:
Why use them: http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html
PHP PDO doc: http://php.net/manual/en/pdo.prepare.php
Here is the core code:
try {
//open database
$dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
//define sql query
$sql = "SELECT LastName FROM staff";
//prepare the query for execution
$qresult = $dbh->prepare($sql);
//insert code below to handle parameters to the sql query here
//execute the query
$qresult->execute();
//fetch the results
foreach ($qresult->fetch(PDO::FETCH_ASSOC) as $row)
{
echo $row['LastName'] . '<br />';
}
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
$qresult = null; //close the result set
$dbh = null; //close the database
Note, that I have replaced the call to query() with a couple of lines that call prepare() then execute(). You can then easily insert the following lines in between the prepare() and execute() calls to handle passing parameterized queries. This will help reduce chances of sql injection.
I have also changed the way you are accessing the retirned valued by specifying that I want them returned as and associative array, PDO::FETCH_ASSOC. This will get you a result set that you can iterate through like you would have using the old mysql interfaces.
If your query was a parameterized query like:
$sql="SELECT LastName FROM staff WHERE LastName=':lastname'";
where :lastname is the parameter.
Here is the code you would insert at the comment to handle this, (this code will handle multiple parameters. Simply add additional elements to the $param array):
//bind parameters to the prepared statement
$param = array(':lastname'=>'Jones');
foreach ($param as $key => $value) {
$qresult->bindValue($key,$value);
}
Make sure you separate the columns in the SELECT with a comma (space on either side of the comma is okay, but not required). If you want to select all columns, have only a * with no other characters.