Looking for an alternative to get_result() [duplicate] - php

I am totally confused by mySQLi. Although I have been using procedural mysql calls for years, I want to get used to making prepared statements for the db security/mySQL injection protection it offers. I am trying to write a simple select statement (yes I know making a procedural call for this offers performance enhancement). When run, I get all the echoes until I hit the $result = $stmt->get_result(); component. It all seems fairly straightforward to me, but I am at a loss after hours of reading manuals on mySQLi. Any ideas why this would be failing?
*note: this is a test environment and while no sanitizing/escaping of characters is taking place, I am only passing valid content into the variables $username and $email. And also, I have looked all over SO to find the solution to my issue.
function checkUsernameEmailAvailability($username, $email) {
//Instantiate mysqli connection
#$mysqli = new mysqli(C_HOST,C_USER,C_PASS,C_BASE) or die("Failed to connect to MySQL database...");
if (!$mysqli)
{
echo 'Error: Could not connect to database. Please try again later...';
exit;
} else {
echo 'mysqli created';
}
/* Create a prepared statement */
if($stmt = $mysqli -> prepare("SELECT username,email FROM tb_users WHERE username=? OR email=?")) {
echo '<br />MYSQLi: ';
/* Bind parameters s - string, b - boolean, i - int, etc */
$stmt -> bind_param("ss", $username, $email);
echo '<br />paramsBound...';
/* Execute it */
$stmt -> execute();
echo '<br />Executed';
$result = $stmt->get_result();
echo '<br />Result acquired';
/* now you can fetch the results into an array - NICE */
$myrow = $result->fetch_assoc();
echo '<br />Fetched';
/* Close statement */
/$stmt -> close();
echo '<br />Done mysqli';
}
}
Also, do I have to instantiate a mysqli every time I call a function? I'm assuming they're not persistent db connects like in procedural mysql. Yes, I am aware this is a scope issue, and no I have not been able to understand the scoping of this class variable. When I declared it outside of the function, it was not available when I came into the function.
UPDATE
if I change line 12 from:
if($stmt = $mysqli -> prepare("SELECT username,email FROM tb_users WHERE username=? OR email=?")) {
to:
$stmt = $mysqli->stmt_init();
if($stmt = $mysqli -> prepare("SELECT username,email FROM tb_users WHERE username=? OR email=?")) {
if(!stmt) echo 'Statement prepared'; else echo 'Statement NOT prepared';
I get Statement NOT prepared. Now I'm even more confused....
UPDATE:
I contacted my hosting provider and apparently mySQLi is supported, and the mysqlnd driver is present. Perhaps there is a way to simply test this? Although they usually have given me pretty knowledgeable answers in the past.
UPDATE...AGAIN: I checked my server capabilities myself and discovered, while mysqli and PDO are present, mysqlnd is not. Thusly, I understand why get_result() will not work (mysqlnd required I think), I still don't understand why the prepared statement itself will not work.

Through some checking, even though mysqli is installed on my host, apparently the mysqlnd driver is not present. Therefore, get_result() can not be used(php manual defines get_result as mysqlnd dependent), and instead extra coding would need to be done to handle my result the way I would like.
Therefore, I decided to try and learn how PDO works, and within minutes, voila!!!
Replaced the above code with this:
function checkUsernameEmailAvailability($username, $email) {
echo 'pdo about to be created';
$dsn = 'mysql:dbname='.C_BASE.';host='.C_HOST;
$user = C_USER;
$password = C_PASS;
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$params = array(':username' => $username, ':email' => $email);
try{
$sth = $dbh->prepare('SELECT username,email FROM tb_users WHERE username = :username OR email = :email ');
} catch(PDOException $e) {
echo 'Prepare failed: ' . $e->getMessage();
}
try{
$sth->execute($params);
} catch(PDOException $e) {
echo 'Execute failed: ' . $e->getMessage();
}
$result = $sth->fetch(PDO::FETCH_ASSOC);
print_r($result);
}
As much error checking as I could think of, and no problems at all first crack at it!
Final Code
function checkUsernameEmailAvailability($username, $email) {
$dsn = 'mysql:dbname='.C_BASE.';host='.C_HOST;
$user = C_USER;
$password = C_PASS;
new PDO($dsn, $user, $password);
$params = array(':username' => $username, ':email' => $email);
$sth = $dbh->prepare('SELECT username,email FROM tb_users WHERE username = :username OR email = :email ');
$sth->execute($params);
$result = $sth->fetch(PDO::FETCH_ASSOC);
print_r($result);
}

mysqli_stmt :: get_result is Available only with mysqlnd package. remove php5-mysql package and install php5-mysqlnd instead

Related

How can I convert this mysqli to PDO?

<?php
require_once('dbconfig.php');
global $con;
$query = $con->prepare("SELECT * FROM userinfo order by id DESC");
$query->execute();
mysqli_stmt_bind_result($query, $id, $name, $username, $password);
You should use ->bindColumn Manual
See also This answer.
Best Practise: Do not use SELECT * instead define each column you need to grab from the table.
Do not globalise your connection variable. This is a security risk as well as adding bloat and should be unneeded on your code.
Because it is a static statement you can use ->query rather than prepare, as nothing needs to be prepared.
Solution:
$query = $con->query("SELECT id,name,username,password FROM userinfo ORDER BY id DESC");
try {
$query->execute();
$query->bindColumn(1, $id);
$query->bindColumn(2, $name);
$query->bindColumn(3, $username);
$query->bindColumn(4, $password);
}
catch (PDOException $ex) {
error_log(print_r($ex,true);
}
Alternatively:
A nice feature of PDO::query() is that it enables you to iterate over the rowset returned by a successfully executed SELECT statement. From the manual
foreach ($conn->query('SELECT id,name,username,password FROM userinfo ORDER BY id DESC') as $row) {
print $row['id'] . " is the ID\n";
print $row['name'] . " is the Name\n";
print $row['username'] . " is the Username\n";
}
See Also:
Mzea Has some good hints on their answer, you should use their $options settings as well as using their suggested utf8mb4 connection character set.
And their suggestion for using ->fetchAll is also completely valid too.
Try this
$dsn = "mysql:host=localhost;dbname=myDatabase;charset=utf8mb4";
$options = [
PDO::ATTR_EMULATE_PREPARES => false, // turn off emulation mode for "real" prepared statements
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, //turn on errors in the form of exceptions
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, //make the default fetch be an associative array
];
try {
$pdo = new PDO($dsn, "username", "password", $options);
} catch (Exception $e) {
error_log($e->getMessage());
exit('Something weird happened'); //something a user can understand
}
$arr = $pdo->query("SELECT * FROM myTable")->fetchAll(PDO::FETCH_ASSOC);

PDO mySql Connection

There is a link that I found a while back. What I would like to know is:
How do I query a simple SELECT * FROM table_name using PDO?
I tried playing around with the examples here but I was not getting any results back. All along I have been using the mysql_connect method which I dont want to use anymore. I would like to use following:
<?php
$host="127.0.0.1"; // Host name
$username="root"; // Mysql username
$password=""; // Mysql password
$db_name="microict-intrasys"; // Database name //
//$id = 5;
try {
$conn = new PDO('mysql:$host;$db_name,', $username, $password);
$stmt = $conn->prepare('SELECT version FROM system_info');
// $stmt->execute(array('id' => $id));
$result = $stmt->fetchAll();
if ( count($result) )
{
foreach($result as $row)
{
print_r($row);
}
}
else
{
echo "No rows returned.";
}
}
catch(PDOException $e)
{
echo 'ERROR: ' . $e->getMessage();
}
?>
First create the pdo instance and connect...
$db = new PDO('mysql:host=127.0.0.1;dbname=yourDBName;charset=utf8', 'username', 'password');
I use charset as well to have the correct formated data here... but you dont have to use it. Connection string could also look like
PDO("mysql:host=127.0.0.1;dbname=yourDBName" , $username, $password);
(using $username & $password here)
since working with pdo i ran into speed issues when i use localhost instead of 127.0.0.1 PDO seems to use the DNS to translate localhost into 127.0.0.1 and this causes speed. And im talking about seconds just for connecting to DBs
after connecting you can query like
$stmt = $db->query("SELECT * FROM table");
and than fetch could results like
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo $row['field1'].' '.$row['field2']; //etc...
}
or
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($result);
so than you should have at least some result.... (simple way)
I guess your problem is...
accourdig to your source you have a issue in your connectionstring....
<?php
$host="127.0.0.1"; // Host name
$username="root"; // Mysql username
$password=""; // Mysql password
$db_name="microict-intrasys"; // Database name
//$id = 5;
try {
$conn = new PDO('mysql:host={$host};dbname={$db_name}', $username, $password);
// you neeeeeed this--^ and this--^
$stmt = $conn->prepare('SELECT version FROM system_info');
$stmt->execute(array('id' => $id));
$result = $stmt->fetchAll();
if ( count($result) )
{
foreach($result as $row)
{
print_r($row);
}
}
else
{
echo "No rows returned.";
}
}
catch(PDOException $e)
{
echo 'ERROR: ' . $e->getMessage();
}
?>
you are missing some in your connection string! kinda typo
your parsed string looks like
"mysql:localhost;microict-intrasys"
and thats wrong. it must look like
//"mysql:host=localhost;dbname=microict-intrasys"
"mysql:host=127.0.0.1;dbname=microict-intrasys" // better
PDO Check
if (!defined('PDO::ATTR_DRIVER_NAME')) {
echo 'PDO unavailable';
}

two mysqli querys, one in a while loop

Can't seam to find the answer to this.
I have a mysqli loop statement. And in that loop I want to run another query. I cant write these two sql together. Is that possible?
I thought since I use stmt and set that to prepare statement. So i add another variable stmt2. Running them seperate works, but run it like I wrote it gives me "mysqli Fatal error: Call to a member function bind_param() on a non-object"
Pseudocode :
loop_sql_Statement {
loop_another_sql_statement(variable_from_firsT_select) {
echo "$first_statement_variables $second_statemenet_variables";
}
}
$sql = "select dyr_id, dyr_navn, type_navn, dyr_rase_id, dyr_fodt_aar, dyr_kommentar, dyr_opprettet, dyr_endret
from dyr_opphald, dyr, dyr_typer
where dyropphald_dyr_id = dyr_id
and dyr_type_id = type_id
and dyropphald_opphald_id = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("i",
$p_opphald_id);
$stmt->execute();
$stmt->bind_result($dyr_id, $dyr_navn, $type_navn, $dyr_rase_id, $dyr_fodt_aar, $dyr_kommentar, $dyr_opprettet, $dyr_endret);
echo "<table>";
while($stmt->fetch()) {
echo "<tr><td>$dyr_navn</td><td>$type_navn</td><td>$dyr_rase_id</td><td>$dyr_fodt_aar</td><td>";
$sql2 = "select ekstra_ledetekst, ekstradyr_ekstra_verdi from dyr_ekstrainfo, ekstrainfo where ekstradyr_ekstra_id = ekstra_id and ekstradyr_dyr_id = ?";
try {
$stmt2 = $mysqli->prepare($sql2);
$stmt2->bind_param("i",
$dyr_id);
$stmt2->execute();
$stmt2->bind_result($ekstra_ledetekst, $ekstra_ledetekst);
echo "<td>";
while($stmt2->fetch()) {
echo "$ekstra_ledetekst => $ekstra_ledetekst<br>";
}
}catch (Exception $e) {}
echo "</td></tr>";
}
echo "</table>";
The answer:
Silly me, I didnt know I had to have two mysqli connection. So the solution was to declare another mysqli connection.
$mysqli = new mysqli($start, $name, $pwd, $selected_db);
$mysqli2 = new mysqli($start, $name, $pwd, $selected_db);
You should be able to do that, although you make have to start a second connection.

PDO Bind Param Trouble

I'm trying to convert my codes to PDO from mysql_query, and starting with this function
function label_for_field($field_name, $table_name) {
$table = array();
// Bind variables to parameters
$param_array = array(':bundle' => $table_name, ':field_name' => $field_name);
// Prepare Query Statement
$query = "SELECT data FROM field_config_instance WHERE bundle = :bundle AND field_name = :field_name";
$STH = $DBH -> prepare($query);
// Execute
$STH -> execute($param_array);
// Set the fetch mode
$STH -> setFetchMode(PDO::FETCH_OBJ);
while ($row = $STH -> fetch()) {
$info = unserialize($row -> data);
$table[] = $info['label'];
}
return $table[0];
}
and I'm trying out just output it to see if it works
include_once ("includes/connect.php");
include ("includes/functions.php");
echo label_for_field("field_account_number", "account_table");
And here's the connect.php
// Include Constants
require_once ("constants.php");
//Establish Connection
try {
$DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
}
catch (PDOException $e) {
echo $e -> getMessage();
}
I don't know if it's because I'm binding the parameters wrong, it just gave me an server error page
"Server error. The website encountered an error while retrieving ......."
Thanks in advance
You need to set the PDO error mode to produce exceptions before you can catch them.
In your connect.php:
try {
$DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
Then you can have a similar try/catch statement in your function to that of your connection file, and use it to show the error in your development environment.
Try this instead to see if you get valid objects returned from the query.
// Prepare Query Statement
$query = "SELECT data FROM field_config_instance WHERE bundle = :bundle AND field_name = :field_name";
$STH = $DBH -> prepare($query);
$STH->bindValue(":bundle", $table_name);
$STH->bindValue(":field_name", $field_name);
$STH->execute();
$STH->setFetchMode (PDO::FETCH_OBJ);
$result = $STH->fetchAll();
var_dump($result);

How to handle PDO exceptions [duplicate]

This question already has answers here:
Why does this PDO statement silently fail?
(2 answers)
Closed 7 years ago.
I'm trying to work with PDO class on php but I have some trouble to find the right way to handle errors, I've wrote this code:
<?php
// $connection alreay created on a class which works with similar UPDATE statements
// I've simply added here trim() and PDO::PARAM... data type
$id = 33;
$name = "Mario Bros.";
$url = "http://nintendo.com";
$country = "jp";
try {
$sql = "UPDATE table_users SET name = :name, url = :url, country = :country WHERE user_id = :user_id";
$statement = $connection->prepare ($sql);
$statement->bindParam (':user_id', trim($id), PDO::PARAM_INT);
$statement->bindParam (':name', trim($name), PDO::PARAM_STR);
$statement->bindParam (':url', trim($url), PDO::PARAM_STR);
$statement->bindParam (':country', trim($country), PDO::PARAM_STR, 2);
$status = $statement->execute ();
} catch (PDOException $e) {
print $e->getMessage ();
}
print $status; // it returns a null value, and no errors are reported
?>
this portion of code doesn't report errors, but it simply doesn't work, the var $status at the bottom, return a null value.
can someone help me to find where I'm wrong?
PDO won't throw exceptions unless you tell it to. Have you run:
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
on the PDO object?
You can add the attribute one time while you connect you mysql.
function connect($dsn, $user, $password){
try {
$dbh = new PDO($dsn, $user, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
exit;
}
}
Thanks

Categories