Convert mysqli to pdo bind_all - php

here is my current code
function getUserDetails($username=NULL, $id=NULL) {
if($username!=NULL) {
$column = "user_name";
$data = $username;
}
elseif($id!=NULL) {
$column = "id";
$data = $id;
}
global $db;
$query = $db->prepare("SELECT id, username, permissions, forename, surname, password, email, courseid, choiceid, lastlogin, active FROM users WHERE $column = :column");
$query->bindParam(":column", $data);
$query->execute();
$query->bind_result ($id, $username, $permissions, $forename, $surname, $password, $email, $courseid, $choiceid, $lastlogin, $active);
while ($query->fetch()){
$row = array('id' => $id, 'userlevel' => $permissions, 'username' => $username, 'forename' => $forename, 'surname' => $surname, 'password' => $password, 'email' => $email, 'courseId' => $courseid, 'choiceId' => $choiceId, 'lastlogin' => $lastlogin, 'active'=> $active);
}
return ($row);
}
I have been trying to convert this to pdo, as I've found out bind_result doesn't work with pdo - could anyone help me as to what I should be doing?
I've read arround that I should be using fetch? But i'm getting really confused.
[edit]
ive tried this:
function getUserDetails($username=NULL,$id=NULL) {
if($username!=NULL) {
$column = "user_name";
$data = $username;
}
elseif($id!=NULL) {
$column = "id";
$data = $id;
}
global $db;
$query = $db->prepare("SELECT id, username, permissions, forename, surname, password, email, courseid, choiceid, lastlogin, active FROM users WHERE $column = :column");
$query->bindParam(":column", $data);
$query->execute();
$results = array();
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$results[] = $row;
}
return ($results);
}
is this a step in the right direction ?
[edit2]
updated my code to this:
function getUserDetails($username) {
global $db;
$query = $db->prepare("SELECT * FROM users WHERE username = :username");
$query->bindParam(":username", $username);
return $query->fetch(PDO::FETCH_ASSOC);
}
$username = 'uname';
$result = getUserDetails($username);
print_r($result);
however it prints nothing. the username definitely exists.
ive tried a test database with some dummy data
$data = '2';
$sth = $db->prepare("SELECT * FROM test WHERE id = :id");
$sth->bindParam(":id", $data);
$sth->execute();
$result = $sth->fetch(PDO::FETCH_ASSOC);
print_r($result);
im trying to figure out how i access what is in the printed array:
the array comes out as
Array ( [Id] => 2 [Name] => tom )
how do i (for example) do
$name = $result['name']; //line 67
when i try that code i get
Notice: Undefined index: name in <directory>\test.php on line 67
Figured it out!
function getUserDetails($username) {
global $db;
$sth = $db->prepare("SELECT id, username, permissions, forename, surname, password, email, courseid, choiceid, lastlogin, active FROM users WHERE username = :username");
$sth->bindParam(":username", $username);
$sth->execute();
$result = $sth->fetch(PDO::FETCH_ASSOC);
return $result;
}
$username = 'un';
$userdetails = getUserDetails($username);
echo $userdetails['forename'];
and it gives me the correct answer!
thanks for your help

YES!
It's great step in the right direction.
As you can see, mysqli is absolutely unusable with prepared statements, both in binding placeholders and returning results.
while PDO can solve your problem using dramatically less code.
You don't need useless bind with PDO at all - just get all results with fetchAll():
function getUserDetails($username=NULL,$id=NULL) {
if ($username) {
$column = "user_name";
$data = $username;
} elseif($id) {
$column = "id";
$data = $id;
} else {
return;
}
global $db;
$query = $db->prepare("SELECT * FROM users WHERE $column = ?");
$query->execute(array($data));
return $query->fetchAll();
}
But wait. Why do you want to return an array if it's users details?
It will add just useless dimension to the returned array.
For this very case make it
return $query->fetch();
instead of fetchAll().
But then you need many rows - use this latter method.
On other methods and useful connect options refer to the tag wiki

Related

PHP - Mysqli | i'm trying to output data but i keep getting empty array

i'm trying to get user information from database, but it keep giving me an empty array.
code : i.stack.imgur.com/Op4HB.png
$information = array();
$user = 'admin';
$myuser = new mysqli(HOST, USER, PASSWORD, DATABASE);
if ($info = $myuser->prepare("SELECT id,username,email,bd,firstname,lastname,gender,ppicture,cpicture FROM members WHERE username = ?")) {
$info->bind_param("s", $user);
/* execute query */
$info->execute();
/* get result */
$result = $info->get_result();
/* bind result variables */
$info->bind_result($information['id'],$information['username'],$information['email'],$information['birthday'],$information['first_name'],$information['last_name'],$information['gender'],$information['profile_picture'],$information['cover_picture']);
$info->fetch();
$rows = $result->num_rows;
$info->close();
}
if (!$rows) {
redirect('http://example.com/');
} else {
print_r($information);
}
this is what i get :
can someone help me in this ? i use mysqli all the time but i don't know what went wrong this time.
thanks.
Try this
Fetch & display the results inside the while loop
if ($info = $myuser->prepare("SELECT id,username,email,bd,firstname,lastname,gender,ppicture,cpicture FROM members WHERE username = ?")) {
$info->bind_param("s", $user);
/* execute query */
$info->execute();
/* get result */
$result = $info->get_result();
/* bind result variables */
$info->bind_result($information['id'],$information['username'],$information['email'],$information['birthday'],$information['first_name'],$information['last_name'],$information['gender'],$information['profile_picture'],$information['cover_picture']);
$rows = $result->num_rows;
}
if (!$rows) {
redirect('http://example.com/');
} else {
while ($info->fetch()) {
print_r($information);
}
}
EDIT
if ($info = $myuser->prepare("SELECT email FROM members WHERE username = ?")) {
$info->bind_param("s", $user);
/* execute query */
$info->execute();
/* bind result variables */
$info->bind_result($email);
$info->fetch();
printf("%s \n", $email);
}
i fixed it myself
i found the answer at http://php.net
thanks anyways !
<?php
$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
$query = "SELECT id,username,email,bd,firstname,lastname,gender,ppicture,cpicture FROM members WHERE username = ?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("s", $user);
$stmt->execute();
$res = $stmt->get_result();
$rows = $res->num_rows;
$information = $res->fetch_assoc();
if($rows == 0 ) {
redirect("http://example.com");
}
print_r($information);
?>
PS: account.php is being required by index.php so it gets '$user' from there
output
Array ( [id] => 15 [username] => admin [email] => admin#theboat.tn [bd] => 2017-02-07 [firstname] => Saif [lastname] => Eddin [gender] => male [ppicture] => 1f4c1b47a3910039e60851c453ae4d80_a.jpg [cpicture] => default_c.jpg )

Storing a value taken from db in a variable

I'm using PDO for the connection to my database. This is the code I'm using:
<?php
session_start();
if (ValidarCreacionUsuario($_POST)) {
if (ValidarNoEmpty($_POST)) {
$connection = new PDO('mysql:host=localhost;dbname=dbname', "dbuser", "dbpass");
$sql = 'SELECT * FROM users WHERE username = :username AND password = :password';
$statement = $connection->prepare($sql);
$statement->bindParam(':username', $_POST['username'], PDO::PARAM_STR, 12);
$statement->bindParam(':password', $_POST['password'], PDO::PARAM_STR, 30);
$result = $statement->execute();
And then, I want to catch the value of the 'sex' column and the value of the 'id' column in my database, so, I think I have to use the fetchAll() or something like this, but I don't know how to use it or if I have to use it.
So, what do I have to use?
Thanks.
something like this will show you what is available to you to use in an associative array (key and value)
$sql = "SELECT * FROM users... etc";
$stmt = $dbh->query($sql);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
/*** loop over the object directly ***/
foreach($result as $key=>$val)
{
echo $key.' - '.$val.'<br />';
}

PHP - for statement in an array

For a PDO execution statement I am trying to make any static information such as column names and array strings to a dynamic array which contains every column from the MySQL table.
The original code was:
$stmt = $conn->prepare("INSERT into data (`username,` `password`, `email`) VALUES username = :username , password = :password , email = :email ");
$stmt->execute(array(
':username' => $entry_username,
':password' => $entry_password,
':email' => $entry_email
));
So far I have been able to change the sql statement to
$sql = "INSERT into DATA (`" . implode('`,`', $columns) . "`) values (:" . implode(',:', $columns) . ")";
$stmt = $conn->prepare($sql);
but have been unable to do a similar thing to the execution array to make it dynamically variating like the statement.
I have tried adding a for statement in the array
for ($i = 0; $i < count($columns); $i++) {
':'.$columns[$i] => ${'entry_'.$columns[$i]};
}
but this hasn't worked.
Any help would be much appreciated.
Thanks in advance!
This is a perfect situation to make good use of a prepared statement.
Try this:
I am kind of assuming what the varuables will be called in the $columns array here.
$stmt = $conn->prepare("INSERT into data
(username, password, email) VALUES( :username , :password, :email )");
$stmt->bindParam(':username', $username, PDO::PARAM_STR);
$stmt->bindParam(':password', $password, PDO::PARAM_STR);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
foreach ( $columns as $column ) {
$username = $column['username'];
$password = $column['password'];
$email = $column['email'];
$result = $stmt->execute();
if ( ! $result ) {
// add some error checking code here
}
}
Basically, your code would look like this.
$entry = array(
'username' => $_POST['username'], //assuming it's comming from the post data or for instance $row['username'] if from previous select statement
'password' => $_POST['password'],
'email' => $_POST['email']
);
$sth = $dbh->prepare('INSERT into data (`username,` `password`, `email`) VALUES (:username, :password, :email)');
$sth->bindValue(':username', $entry['username'], PDO::PARAM_INT);
$sth->bindValue(':password', $entry['password'], PDO::PARAM_STR);
$sth->bindValue(':email', $entry['email'], PDO::PARAM_STR);
$sth->execute();
If you want the bound variables to be dynamically created, then you need to create with a loop the bindValue rows:
$entry = array(
'username' => $_POST['username'], //assuming it's comming from the post data or for instance $row['username'] if from previous select statement
'password' => $_POST['password'],
'email' => $_POST['email']
);
$sth = $dbh->prepare('INSERT into data (`username,` `password`, `email`) VALUES (:username, :password, :email)');
foreach($entry as $key => $value) {
$sth->bindValue(':'.$key, $entry[$key], PDO::PARAM_STR);
}
$sth->execute();
or inside the foreach
$sth->bindValue(':'.$key, $value, PDO::PARAM_STR);
Since your keys are (username, password, email) their keynames will be initiated to $key variable, and their values to the $value variable. in the first case it will produce:
$sth->bindValue(':username', $entry['username'], PDO::PARAM_INT);
$sth->bindValue(':password', $entry['password'], PDO::PARAM_STR);
$sth->bindValue(':email', $entry['email'], PDO::PARAM_STR);
Which will be evaluated to:
$sth->bindValue(':username', $_POST['username'], PDO::PARAM_INT);
$sth->bindValue(':password', $_POST['password'], PDO::PARAM_STR);
$sth->bindValue(':email', $_POST['email'], PDO::PARAM_STR);
In the second case it will be directly evaluated.
Have in mind it's completely unacceptable to dynamically create the column names in the query. And you have to reason to do it. However, not a full query is also hard to be read from the other developers. It's enough for you to dynamically create the bound values. You can make a method do it for you. For instance, if you column names in the query are the same way aliased, as the names of the input fields, you will have nothing more to do, but to execute the query.
Let's say you have that helper method:
Class DBConnect {
private $_driver = "mysql";
private $_dbname = "xxxx";
private $_host = "xxxx";
private $_user = "xxxx";
private $_password = "xxxx";
private $_port = 3306;
private $_dbh;
public function __construct($driver = NULL, $dbname = NULL, $host = NULL, $user = NULL, $pass = NULL, $port = NULL) {
$driver = $driver ?: $this->_driver;
$dbname = $dbname ?: $this->_dbname;
$host = $host ?: $this->_host;
$user = $user ?: $this->_user;
$pass = $pass ?: $this->_password;
$port = $port ?: $this->_port;
try {
$this->_dbh = new PDO("$driver:host=$host;port=$port;dbname=$dbname", $user, $pass);
$this->_dbh->exec("set names utf8");
} catch(PDOException $e) {
echo $e->getMessage();
}
}
public function query($sql) {
$sth = $this->_dbh->prepare($sql);
foreach ($_REQUEST as $key => $value) {
if(is_int($value)) {
$param = PDO::PARAM_INT;
} elseif(is_bool($value)) {
$param = PDO::PARAM_BOOL;
} elseif(is_null($value)) {
$param = PDO::PARAM_NULL;
} elseif(is_string($value)) {
$param = PDO::PARAM_STR;
} else {
$param = FALSE;
}
$sth->bindValue(":$key", $value, $param);
}
$sth->execute();
$result = $sth->fetchAll();
return $result;
}
}
So, lets say in another class you have a lot of queries, separated by methods:
public function getFirstQuery() {
$sql = "SELECT
col1, col2
FROM table1
WHERE col3 = :col3;";
$query = $this->_db->query($sql);
return $query;
}
public function inserSecondquery() {
$sql = "INSERT INTO
`table1`
(col1, col2)
VALUES
((SELECT
id
FROM table2
WHERE col8 = :col8), :post_field_5);";
$query = $this->_db->query($sql);
return $query;
}
Assuming you have called these queries the query() method which also fetches the data, the select one you can foreach to retrieve the data, and the insert one you can just call, to insert data. The only rule here is the post fields should be named same way, for example <input name="post_field_5" />
You can also take a look here: PDO Dynamic Query Building
OK, it seems you need to find library for active record like the ones CodeIgniter uses, or... use CodeIgniter.
From the official documentation:
http://ellislab.com/codeigniter/user-guide/database/helpers.html
$this->db->insert_string();
This function simplifies the process of writing database inserts. It
returns a correctly formatted SQL insert string. Example: $data =
array('name' => $name, 'email' => $email, 'url' => $url);
$str = $this->db->insert_string('table_name', $data);
The first parameter is the table name, the second is an associative
array with the data to be inserted. The above example produces: INSERT
INTO table_name (name, email, url) VALUES ('Rick', 'rick#example.com',
'example.com')
So, in your case, you can have something like this:
<form action="" method="post">
<input type="text" name="username" value="testUser123" />
<input type="password" name="password" value="yourPass666" />
<input type="text" name="email" value="email#example.com" />
<input type="submit" value="submit" />
</form>
<?php
//... extending CI
//... opening a method
$table = 'data';
//comming from somewhere, let's dynamically populated array but for testing purpose I will hardcode:
$columns('username', 'password', 'email');
foreach($columns as $column) {
$data[$column] = $_POST[$column]; // this will produce $data=array('username'=>$_POST['username'],password=....);
}
$str = $this->db->insert_string($table, $data);
?>
If you submit the form in the beginning, you will have:
INSERT INTO data (username, password, email) VALUES ('testUser123', 'yourPass666', 'email#example.com');
The whole active record class doc (insert chosen here)
http://ellislab.com/codeigniter/user-guide/database/active_record.html#insert
If you don't have to stick to the for loop, I would suggest a foreach, which should be easier (I know the little problems with for too).
foreach ($element in $array)
{
code execution here
}
Your array element is then stored in the $element (or as you like to name it) and you can execute the command found there.
Is this what you're looking for or did I get you wrong?

Return mysqli query result as an array in PHP

I've been searching the internet for a while now, but since I'm new to MySQLi, I cannot solve this problem myself. This is my code so far. I want to return the result as an array.
function myFunction($u_id, $mysqli){
$userinfo = "SELECT email, name, street, placename FROM users WHERE u_id = ? LIMIT 1";
if($stmt = $mysqli->prepare($userinfo)) {
$stmt->bind_param('i', $u_id);
$stmt->execute();
if(!$stmt->execute()) {
echo $stmt->error.' in query: '.$userinfo;
} else {
//this is what i found somewhere on the internet, and it gives me an array with the right keys but empty values.
$meta = $stmt->result_metadata();
while ($field = $meta->fetch_field()) {
$var = $field->name;
$$var = null;
$parameters[$var] = &$$var;
}
return $parameters;
}
$stmt->close();
}}
Hopefully someone can help me get this code working, or help me find an alternative.
Have you looked at using fetch_array
http://php.net/manual/en/mysqli-result.fetch-array.php
Working from your code
function myFunction($u_id, $mysqli){
$userinfo = "SELECT email, name, street, placename FROM users WHERE u_id = ? LIMIT 1";
if($stmt = $mysqli->prepare($userinfo))
{
$stmt->bind_param('i', $u_id);
$stmt->execute();
if(!$stmt->execute())
{
echo $stmt->error.' in query: '.$userinfo;
}
else {
//this is what i found somewhere on the internet, and it gives me an array with the right keys but empty values.
$parameters = array();
while ($row = $stmt->fetch_assoc()) {
$parameters[] = $row;
}
$stmt->close();
return $parameters;
}
$stmt->close();
}
}

PDO library with better parameter placement

Don't get me wrong PDO is great but what I don't like about it, is how variables are placed far away from the place they belong inside the SQL statement. Meaning I have a query like:
$stmt = $dbh->prepare("SELECT * FROM users WHERE email = ? AND pass = ?");
The variables that are replacing the ? are always far away some lines below:
$stmt->bindParam(1, $email);
$stmt->bindParam(2, $pass);
If you have a lot of parameters this can get quite ugly. Using :email instead of ? does not make it much better. Sometimes you see the parameters as array in the same methode like:
$db->query("SELECT * FROM users WHERE email = ? AND pass = ?",
array($email, $pass));
A little bit better but with 10 variables it is still ugly. You practically create a variable ? you only use once. Also code highlighting is not supported for this pseudo variable.
I think it would be nicer to have it like this
$db->prepare("SELECT * FROM user WHERE email = ", $email, " AND pass = ", $pass);
You could even include the parameters of binParam() like this:
$db->prepare_new(
"SELECT * FROM user WHERE email = ", array($email, PDO::PARAM_STR),
" AND pass = ", $pass);
I wounder if there is a library that supports this type of style. Do you know one?
If always every even parameter will be parameter you can do it like this:
class MyPDO extends PDO {
public function prepareQuery() {
$query_str = "";
$params = array();
foreach(func_get_args() as $key => $param) {
if( $key % 2 == 0 ) {
$query_str .= $param;
}
else {
$params[] = $param;
$query_str .= ' ? ';
}
}
$prepared = $this->prepare($query_str);
foreach( $params as $key => $param ) {
$prepared->bindParam( $key+1, $param );
}
return $prepared;
}
}
and then you can use it as you wanted:
$db = new MyPDO( .. );
$db->prepareQuery("SELECT * FROM user WHERE email = ", $email, " AND pass = ", $pass);
PS: not tested - just a concept
A lot of the point of having ? and :email is that you can reuse the query multiple times. For example:
$stmt = $pdo->prepare("SELECT true FROM user WHERE email = :email");
$stmt->execute(array($email1));
$stmt->execute(array($email2));
// etc.
Having specific variables in the query removes this functionality entirely.
If you wanted, you could always extend or comprise PDO, though:
class DB {
private $pdo;
public function executeQuery($query, $args) {
$stmt = $this->pdo->prepare($query);
$stmt->execute($args);
}
}
$db->executeQuery("SELECT true FROM user WHERE email = :email", array($email1));
This hides the functionality of PDO that you dislike.
UPDATE:
This is an unusual way of doing things, but it seems to be what you're after:
$pdo->query("SELECT true FROM user WHERE email = " . $pdo->quote($email));
http://us2.php.net/manual/en/pdo.quote.php
You could put something similar to this into a function:
$stmt = $dbh->prepare("SELECT * FROM users WHERE email = :email AND pass = :pass");
$arr = array(
'email' => 'test#test.com',
'pass' => 'secret'
);
foreach($arr as $key => $val){
$stmt->bindParam(':'.$key, $val);
}
Example:
function myBindParams($stmt, $bindings){
foreach($bindings as $key => $val){
$stmt->bindParam(':'.$key, $val);
}
return $stmt;
}
$stmt = $dbh->prepare("SELECT * FROM users WHERE email = :email AND pass = :pass");
$arr = array(
'email' => 'test#test.com',
'pass' => 'secret'
);
$stmt = myBindParams($stmt, $arr);

Categories