there. I'm migrating from mysql to PDO structure, and i had an issue when tryign a foreach statement, if i could get some help, would appreciate. the structure that doesn't work is:
foreach ($con -> query('SELECT MIN(LEAST(L1_RMS, L2_RMS, L3_RMS)) AS menor_valor FROM afunda_eleva') as $array_min_afund)
{
$intensidade_elevacao[] = $array_min_afund['menor_valor'];
}
where
$con is my variable to connect to the database. (working fine).
The error that i get when i run this is:
"Invalid argument supplied for foreach()"
The problem is that i've used this same structure some lines beyond this in the program and it worked. Does anyone know a possible reason for this to be happening? Thanks in advance!
EDIT
$result = ($con -> query('SELECT MIN(LEAST(L1_RMS, L2_RMS, L3_RMS)) AS menor_valor FROM afunda_eleva'));
while ($row = $result -> fetch_assoc())
{
$intensidade_elevacao[] = $row['menor_valor'];
}
Something you're going to want to do is get PDO to throw exceptions. They're much harder to miss than warnings and errors.
Here's the PDO constructor I use...
$con = new PDO('mysql:host=localhost;dbname=your_db_name;charset=utf8', 'username', 'password', array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC));
Now, assuming your query actually works, it's only going to return one row with one column so try the following
$stmt = $con->query('SELECT MIN(LEAST(L1_RMS, L2_RMS, L3_RMS)) AS menor_valor FROM afunda_eleva');
$menor_valor = $stmt->fetchColumn();
Related
My Question Is About Fetching Data From Database But Displaying Empty Array.
I Connected DB by PDO and else you can see in code. Suggestions In Code it will great Help.
try{
$tododb = new PDO('mysql:host = localhost;dbname = mytodo;charset=utf8','root',''); //Connect to the db
$statement = $tododb->prepare('select * from todos');
$statement->execute();
var_dump($statement->fetchAll(PDO::FETCH_OBJ));
}
catch(PDOException $e){
echo 'Exception -> ';
var_dump($e->getMessage());
die();
}
Not sure what else may be failing, but in your connect, you need to remove the spaces around the '='
$tododb = new PDO('mysql:host=localhost;dbname=mytodo;charset=utf8','root',''); //Connect to the db
In general, PDOStatement:fetchAll() returns an empty array in case your query returned no data.
It means that todos table is empty.
However, in your case it's both your inaccuracy with PDO credentials and insufficient error reporting. You didn't tell PDO to throw an exception in case of a database error.
As of parameters, you should never ever "decorate" them adding spaces or other unnecessary stuff.
And as of error reporting, always put PDO in Exceptuion mode so it could give you a clue.
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
PDO::ATTR_EMULATE_PREPARES => false,
];
$tododb = new PDO('mysql:host=localhost;dbname=mytodo;charset=utf8','root','', $options);
$statement = $tododb->prepare('select * from todos');
$statement->execute();
var_dump($statement->fetchAll());
I'm trying to select a row from a table using mysqli but all I can get is a bunch of null values and I don't really know why. The same query works using normal php mysql and if I try to perform the same query on phpMyAdmin using the parameter I pass goes through fine.
Here's the code:
$con = mysqli_connect('localhost', 'user', 'pass',"db");
if (mysqli_connect_errno()){
die("Failed to connect to MySQL: " . mysqli_connect_error());
}
$coupon = $_GET['coupon'];
$sql = mysqli_prepare($con, "SELECT * FROM coupon WHERE coupon=?");
$sql->bind_param('s', $coupon);
$sql->execute();
$sql->store_result();
echo $sql;
returns
"affected_rows":null,
"insert_id":null,
"num_rows":null,
"param_count":null,
"field_count":null,
"errno":null,
"error":null,
"error_list":null,
"sqlstate":null,
"id":null
I already tried to search for an answer either here and on google but I couldn't find anything close to my problem.
What am I doing wrong?
You must decide if you're using procedural or OOP approach. From your code, it seems you call the procedural version of mysqli extension and afterwards you try using objects. See the documentation examples, both object oriented and procedural and decide on a single one.
author's final solution (moved from question content):
As suggested by user #RiggsFolly I wasn't fetching the results at all, plus I was mixing procedural and OOP approaches as suggested by user #Alex . Here's the working code for future reference to anyone who will arrive here with a similar problem:
$coupon = $_GET['coupon'];
if ($sql = mysqli_prepare($con, "SELECT * FROM coupon WHERE coupon=?;")){
mysqli_stmt_bind_param($sql, 's', $coupon);
mysqli_stmt_execute($sql);
mysqli_stmt_bind_result($sql, $ID, $coupon, $discount, $uses);
mysqli_stmt_fetch($sql);
$data = array(
'ID' => $ID,
'coupon' => $coupon,
'discount' => $discount,
'uses' => $uses
);
echo json_encode($data);
}else{
echo json_encode(FALSE);
}
I am trying to use PDO and prepared statements to get the primary key of a table. From other questions I saw that this is possible when executing something like this:
show index from TABLENAME where Key_name = 'PRIMARY'
The problem is that I can not use this from inside a prepared statement by using PDO under PHP. The code I use is the following:
$pdo = new PDO('mysql:host=localhost;charset=utf8;dbname=eclass', "user", "pass");
$stm = $pdo->prepare("show index from `TABLENAME` where `Key_name` = 'PRIMARY'");
$res = $stm->execute();
Now, the problem is that although the statement is created correctly, the execution fails. I am sure that this is not a permission's problem, since I run this as root with no result. When I directly run this SQL code from mysql prompt, it shows result indeed.
EDIT: It seems that after the weekend, the statement magically works. I don't know why this happened. Thank you for your help.
are you sure it fails? what is the result of this code?
$pdo = new PDO(
"mysql:dbname=" . SQL_DB . ";host=" . SQL_HOST, SQL_USER, SQL_PWD,
array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
)
);
try {
$stm = $pdo->prepare("show index from `TABLENAME` where `Key_name` = 'PRIMARY'");
$res = $stm->execute();
print_r($stm->fetch(PDO::FETCH_ASSOC));
} catch (Exception $e) {
print_r($e);
}
I have omitted unnecessary code. Whenever I try to run this, it processes without any errors. However, in the update query, whenever I use WHERE student_id='$student_id', it doesn't update. No errors, it just doesn't update. However, when I use the numeric equivalent of the variable, such as 1, it works just fine. What am I missing? Thank you!
$resolved_student_id = $_GET['student_id'];
try {
$request_sd = $db -> prepare("SELECT student_name,tutor,intervention FROM students WHERE student_id='$resolved_student_id'");
$request_sd -> execute();
} catch ( Exception $e ) {
echo "Could not query database.";
exit;
}
$studentdata = $request_sd -> fetch();
if ( empty( $_POST ) === false ) {
if ( empty( $_POST['student_name'] ) === true || empty( $_POST['student_tutor'] ) === true || empty( $_POST['student_intervention'] ) === true ) {
$updateStudentInformation = "You need to fill out all fields.";
} else {
$student_name = $_POST['student_name'];
$student_tutor = $_POST['student_tutor'];
$student_intervention = $_POST['student_intervention'];
try {
$updatedata = $db -> prepare("UPDATE students SET student_name='$student_name', tutor='$student_tutor', intervention='$student_intervention' WHERE student_id='$resolved_student_id'");
$updatedata -> execute();
} catch (Exception $e) {
echo "Could not update database.";
exit;
}
header("location: edit.php");
}
}
How come you are using both get and post methods here?
I guess this: $resolved_student_id = $_GET['student_id'];
Should be replaced by: $resolved_student_id = $_POST['student_id'];
and if you need both methods make sure to specify the GET data in the form URL.
eg:<form method="POST" action="abc.php?student_id=1">
And the reason its not updating where $student_id is you have not defined any such variable, not at least what i can see here in the code u posted.
You've written your query as a straight up query (where all the options are defined) but you're running prepare, where your query would look like this
UPDATE students SET student_name=?, tutor=?, intervention=? WHERE student_id=?
Then you would run bind_param to bind your data to the prepared statement and then execute()
So either convert your query to a prepared statement query and bind your parameters or change from prepare to query
Several things here...
Configure PDO to throw exceptions. I like using this constructor for optimal MySQL usage
$db = new PDO('mysql:host=localhost;dbname=db_name;charset=utf8', 'username', 'password', array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC));
Stop catching exceptions and discarding them. This is most important while developing. Once you're confident that your code runs properly, then you can implement a high-level exception handling scheme. Simply remove the try controls and catch blocks from your code
Use parameter binding with your queries instead of string interpolation. This will make your queries much more resilient to SQL injection attacks.
$request_sd = $db->prepare("SELECT student_name,tutor,intervention FROM students WHERE student_id = ?");
$request_sd->execute([$resolved_student_id]);
// use array($resolved_student_id) if using an older version of PHP
You would do the same with your update query.
I managed to run the following code to insert into my table on first try. Then, I deleted that row in PHPMyAdmin to test my code further. I also noticed that it didn't get deleted on the 1st try. Only after few try. This might be due to I didn't set the $pdoHandle to NULL after I'm done with the query.
Then, unfortunately I couldn't insert new row on subsequent run. I even tried to change the input value and to avail I was unable to insert new row. The following are my PHP codes:
public function CreateNewCustomer($userId,$password,$name,$email)
{
$userId = filter_var($userId,FILTER_SANITIZE_STRING);
$password = filter_var($password,FILTER_SANITIZE_STRING);
$password = sha1($password);
$name = filter_var($name,FILTER_SANITIZE_STRING);
$email = filter_var($email,FILTER_SANITIZE_EMAIL);
do{
$customerId = hexdec(bin2hex(openssl_random_pseudo_bytes(4,$isStrong)));
echo $customerId;
$result = $this->connObject->exec("SELECT COUNT(id) FROM customer_tbl WHERE id=$customerId");
var_dump($result);
}while($result>0);
$statement = $this->connObject->prepare("INSERT INTO customer_tbl (id,name,email) VALUES ($customerId,:name,:email)");
$result = $statement->execute(array(':name'=>$name,':email'=>$email ));
var_dump($result);
$statement = $this->connObject->prepare("INSERT INTO login_tbl (username,password,customer_id) VALUES (:userName,PASSWORD(:password),$customerId)");
$result = $statement->execute(array(':userName'=>$userId,':password'=>$password ));
var_dump($result);
}
I used the following code to access the above method.
function Test($userName,$password,$name,$email)
{
try
{
$dbConnect = new DbConnect();
$pdoHandle = $dbConnect->Connect();
$userAccess = new UserAccess($pdoHandle);
$userAccess->CreateNewCustomer($userName,$password,$name,$email);
}
catch(PDOException $e)
{
$pdoHandle = null;
var_dump($e);
}
$pdoHandle = null;
}
Test('tester','password','TestX','test#example.com');
The var_dump of results is always false.
Is there any problem with my codes or is it something wrong with the database?
UPDATE/SOLUTION:
I just read through the PHP document on PDO::exec() and one of the user contributed notes mentioned that you can't use any SELECT statements (even thou the above only returns the count value) and any statements which might return a rows. The return value of PDO::exec() is the number of affected rows (integer), so the PDOStatement::closeCursor() can't be used to solve it. Even when I set the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY=>true, it still doesn't work.
So, don't use PDO::exec() for any SELECT. I changed my code to PDO::query() instead as below,
do{
$customerId = hexdec(bin2hex(openssl_random_pseudo_bytes(4,$isStrong)));
$statement = $this->connObject->query("SELECT COUNT(id) FROM customer_tbl WHERE id=$customerId");
$statement->execute();
}while($statement->fetchColumn(0)>0);
Hope this would be helpful to anyone looking for a solution with similar problem and always remember to read the PHP document first including the user contributions.
Maybe not the answer but here are some things that you can do if you cannto see an obvious error:
If execute returns false, you can get more information about the error that happened by:
$arr = $statement->errorInfo();
print_r($arr);
or you can set different error reporting modes (e.g. throw an exception instead of the defaultsilent mode):
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
This should help you to find the "real" error.
As it turned out (see comments below question), in this case the real error was:
"Cannot execute queries while other unbuffered queries are active.
Consider using PDOStatement::fetchAll(). Alternatively, if your code
is only ever going to run against mysql, you may enable query
buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY"
In this case you have 2 options:
you can set the option to use buffered queries
$dbh = new PDO(’mysql:host=localhost;dbname=test’, ‘root’, ” ,array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true))
or change your code and close an open cursor (may depend on the db driver you are using). You always should read the documentation which covers a lot of default problems.
Hope this helps.
I'm assuming the method is inside the UserAccess class and the connection you pass in is set to the local $this->connObject.
I suspect after you deleted the record, $customerId is being set to null in your interesting do-while loop with the select statement. If the id column in the DB is a non-null primary key field and you try to insert an explicit null it will fail.
Also, no need to keep setting your DB connection to null... this isn't C and connections aren't persistent (unless you explicitly declare them as such).