I have the following code that calls a DB function that retrieves all rows from a table and then echo's them in JSON.
$key = $db->getKeyPermissions();
if ($key != false) {
// use is found
$response["error"] = FALSE;
$response["key"]["endpoint_name"] = $key["endpoint_name"];
$response["key"]["live"] = $key["live"];
$response["key"]["activity_name"] = $key["activity_name"];
echo json_encode($response);
} else {
This is the DB function
public function getKeyPermissions()
{
$stmt = $this->conn->prepare("SELECT * FROM key_permissions WHERE 1");
if ($stmt->execute()) {
$key = $stmt->get_result()->fetch_assoc();
$stmt->close();
return $key;
} else {
return NULL;
}
}
This all works fine except that it only returns the first row and then stops. Read that you have to loop the fetch_assoc() but I couldn't get this working. I would like all rows to be pushed into $key and returned, but all attempts result in an array conversion and non-object errors. Can somebody help me along the way?
EDIT:
public function getKeyPermissions()
{
$stmt = $this->conn->prepare("SELECT * FROM key_permissions WHERE 1");
if ($stmt->execute()) {
$key = array();
while($row = $stmt->get_result()->fetch_assoc()) { //Call to a member function fetch_assoc() on a non-object
$key .= $row; // Array to string conversion
}
$stmt->close();
return $key;
} else {
return NULL;
}
}
You want to call get_result exactly once, and fetch_assoc as long as there are rows:
$result = $stmt->get_result();
$key = array();
while ($row = $result->fetch_assoc()) {
$key[] = $row;
}
return $key;
Related
I've a class with viewData() method that pull the data from the DB table.
I want to return the data result array in Class and iterate the array in Object
I'm able to make it work with fetchAll() but couldn't figure it out how to return the result with fetch() using while loop.
<?php
class CrudClass{
private $db;
function __construct($DB_con){
$this->db = $DB_con;
}
/* DATA VIEW METHOD */
public function viewData(){
$sql = "SELECT * FROM tbl_users";
$stmt = $this->db->prepare($sql);
$stmt->execute();
while($row=$stmt->fetch(PDO::FETCH_ASSOC)) {
return $row; // it doesn't work
}
// below code is working
/*if($stmt->rowCount()>0){
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $result;
}*/
}
}
// instantiate an Object
$obj = new CrudClass($DB_con);
$rows = $obj->viewData();
foreach($rows as $row) {
echo $row['first_name']. " ". $row['last_name'] ."<br>";
}
?>
The reason I want to do that way, because I don't want to pull the data at one go with fetchAll. Instead want to loop through each row at a time. Any help will be appreciated.
You should return array.
$result = []; // initiate the array
while($row=$stmt->fetch(PDO::FETCH_ASSOC)) {
return $result[] = $row; // put each row in the result array
}
return $result; // return the result array
Now the whole method will look something like below
/* DATA VIEW METHOD */
public function viewData() {
$sql = "SELECT * FROM tbl_users";
$stmt = $this->db->prepare($sql);
$stmt->execute();
$result = []; // initiate the array
while($row=$stmt->fetch(PDO::FETCH_ASSOC)) {
return $result[] = $row; // put each row in the result array
}
return $result; // return the result array
}
This way you are assured that even if there is no result set, only array will get returned.
If above doesn't work. Try following two solutions.
1.Test explicitly for false.
while(($row = $stmt->fetch(PDO::FETCH_ASSOC) !== false) {
return $result[] = $row; // put each row in the result array
}
2.Use foreach
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
return $result[] = $row; // put each row in the result array
}
It is possible to return something you can use in a foreach without having to preload all the results (i.e. using PDOStatement::fetchAll()) and without returning the PDOStatement itself -- if that's what you are trying to do.
Because PDOStatement implements Traversable you you can construct an IteratorIterator from the PDOStatement and return that.
class CrudClass
{
public function viewData()
{
$sql = "SELECT * FROM tbl_users";
$stmt = $this->db->prepare($sql);
$stmt->execute();
return new \IteratorIterator($stmt);
}
}
// instantiate an Object
$obj = new CrudClass($DB_con);
$rows = $obj->viewData();
foreach($rows as $row) {
echo $row['first_name']. " ". $row['last_name'] ."<br>";
}
Note that if you were try and foreach over $rows more than once, it will error because because the results of a PDOStatement cannot be rewound.
I am trying to fetch multiple rows in form of an array and then converting it to json
Heres my code :
public function getTest($standard,$chapid,$count)
{
if($count>0)
{
$stmt = $this->conn->prepare("SELECT question from questions where standard=? and chapterId=? ORDER BY rand()");
$stmt->bind_param("ss", $standard,$chapid);
$result=$stmt->execute();
echo $result;
$stmt->close();
$rows = $this->resultToArray($result);
echo json_encode($rows);// Array of rows
}
else
{
$rows["success"] = 0;
$rows["message"] = "Posts NOT Available!";
}
echo json_encode($rows);
}
public function resultToArray($result) {
$rows["success"] = 1;
$rows["message"] = "Post Available!";
$rows["posts"] = array();
while($row = $result->fetch_assoc()) // <--Getting ERROR OVER HERE
{
array_push($rows["posts"], $row);
}
return $rows;
}
I am new to php so I can't figure out why I am getting an error in resultToArray() function on while line.
You need to fetch the results of your query; fetch(PDO::FETCH_ASSOC) will return each result as an associative array:
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
array_push($results, $row);
}
Your $result passed to your function resultToArray() is in fact a bool. You are passing the wrong variable.
I want to loop through all rows in the database and display them to the user, but I'm only getting the first row in my output.
Here is my code::
Query function:
public function query($sql, $params = array()) {
$this->_error = false;
if($this->_query = $this->_pdo ->prepare($sql)) {
$x = 1;
if(count($params)) {
foreach ($params as $param) {
$this->_query->bindValue($x,$param);
$x++;
}
}
if($this->_query->execute()) {
$this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
$this->_count =$this->_query->rowCount();
} else {
$this->_error = true;
}
}
return $this;
}
public function results() {
return $this->_results;
}
My query:
$search = DB::getInstance()->query("SELECT * FROM staff_info WHERE staff_id = ?",array(
Input::get('staff_id')));
if($search->count()){
if($search) {
$search_result = $search->results();
foreach ($search_result as $val) {
$fname = $val->fname;
$surname = $val->surname;
$street = $val->street;
echo '<div class="table-responsive table-bordered">
<table class="table">
<tr>
<td>'.$fname.'</td>
<td><a href="index.php?ad=profile">'.$surname.'</td>
<td><a href="index.php?ad=profile">'.$street.'</td>
</tr>
</table>
</div>';
}
}
The problem is -- I am getting only the first row even if there are more other rows in the database. Any ideas why this is happening?
You have missed out the underscore.
In your query function you are storing output in $this->_results. You need to correct your variable name before looping. $search->_results.
Using PDO methods prepare(),execute() & fetchAll() or fetch(). Notice I have called my method findAll() so as not to confuse it with PDOs fetchAll(). The following code is based on my usage.
In Class
For all results
public function findAll($sql,$param) {
$query = $this->dbh->prepare($sql);
if(is_array($param)){
$query->execute($param);//1 parameter
}else {
$query->execute(array($param));// >1 parameters
}
$rows = $query->fetchAll();
if($rows){
return $rows;
}
}
}
For one result
public function findOne($sql,$param) {
$query = $this->dbh->prepare($sql);
if(is_array($param)){
$query->execute($param);//1 parameter
}else {
$query->execute(array($param));// >1 parameters
}
$row = $query->fetch();
if($row){
return $row;
}
}
}
Usage
$params=array(100,"AK");
$sql1 = "SELECT * FROM users WHERE id < ? AND state = ?";
$rows = $dao->findAll($sql,$params);
foreach($rows as $row){//Remove for 1 result
echo $row['firstname'];
etc.....
if you want to find one record only you can replace fetchAll() with fetch() in a new method and just echo without foreach()
I'm having some issue with two functions at the moment; I'm trying to get an array to pass from the first function to the other--but for some reason I cannot get it to work.
function getResourceXML($id)
{
$xml = simplexml_load_file('resources.xml');
foreach($xml->children()->children() as $children)
{
if($children['id'] == $id)
{
$resource[] = $children["income"];
return $resource;
}
}
}
function getResourceMultiplier()
{
$sql = "SELECT resourceArray FROM starinformation WHERE starOwner = :uid";
$que = $this->db->prepare($sql);
$que->bindParam('uid', $this->uid);
try
{
$que->execute();
while($row = $que->fetch(PDO::FETCH_BOTH))
{
$resource = $this->getResourceXML($row[0]);
return $resource;
}
}
catch(PDOException $e) {}
}
Move the return statement to after the loop } in both functions or else you only get one loop iteration. Also, in getResourceMultiplier() you're not creating an array. You need (or similar):
$resource[] = $this->getResourceXML($row[0]);
I forget where I copied it from (I think a user posted it on php.net) but this function for fetching results of prepared and normal MySQLi statements is not returning any results when used with statements that contain a simple INNER JOIN, at least the one I tried:
function fetch($result){
$array = array();
if($result instanceof mysqli_stmt){
$result->store_result();
$variables = array();
$data = array();
$meta = $result->result_metadata();
while($field = $meta->fetch_field()){
$variables[] = &$data[$field->name];
}
call_user_func_array(array($result, 'bind_result'), $variables);
$i=0;
while($result->fetch()){
$array[$i] = array();
foreach($data as $k=>$v)
$array[$i][$k] = $v;
$i++;
}
}elseif($result instanceof mysqli_result){
while($row = $result->fetch_assoc())
$array[] = $row;
}
return $array;
}
I've been trying to use it like so (all these functions are methods of the class $database):
function query($str, $values){
if($stmt=$this->sql->prepare($str)){
$types=$this->castArrayAsString($values); //returns a string of $values's types for bind_params
array_unshift($values, $types);
call_user_func_array(array(&$stmt, 'bind_param'), $this->makeValuesReferenced($values));
$stmt->execute();
$result=$this->fetch($stmt); //the function I'm having problems with
if(empty($result)){
$return=true;
}else{
$return=$result;
}
$stmt->close();
}else{
echo $this->sql->error;
$return=false;
}
return $return;
}
This returns nothing:
$list=$database->query("SELECT a.field1, b.field2 FROM table1 AS a INNER JOIN table2 AS b ON a.id_table2=b.id WHERE a.someid=?", array($someid));
This works fine:
$list=$database->query("SELECT field1, field2 FROM table1 WHERE someid=?", array($someid));
If I print out the meta data from fetching the result, it shows that fields are selected, etc, but still gives no final results in the fetch() func.
Any help is appreciated,
Thanks
EDIT HERE IS THE WHOLE CLASS
<?php
class database{
var $HOST="xx.xx.xx.xxx";
var $USER="xxxxxxxxxxx";
var $PASS='xxxxxxxxxx';
var $DATABASE="my_database";
var $sql;
function database(){
$this->sql=new mysqli($this->HOST, $this->USER, $this->PASS, $this->DATABASE);
if($this->sql->connect_errno){
echo "ERROR - No MySQL connection: ".$mysqli->connect_error;
exit;
}
}
function query($str, $values){
if($stmt=$this->sql->prepare($str)){
$types=$this->castArrayAsString($values);
array_unshift($values, $types);
call_user_func_array(array(&$stmt, 'bind_param'), $this->makeValuesReferenced($values));
$stmt->execute();
$result=$this->fetch($stmt);
if(empty($result)){
$return=true;
}else{
$return=$result;
}
$stmt->close();
}else{
echo $this->sql->error;
$return=false;
}
return $return;
}
function fetch($result){
$array = array();
if($result instanceof mysqli_stmt){
$result->store_result();
$variables = array();
$data = array();
$meta = $result->result_metadata();
while($field = $meta->fetch_field()){
$variables[] = &$data[$field->name];
}
call_user_func_array(array($result, 'bind_result'), $variables);
$i=0;
while($result->fetch()){
$array[$i] = array();
foreach($data as $k=>$v)
$array[$i][$k] = $v;
$i++;
}
}elseif($result instanceof mysqli_result){
while($row = $result->fetch_assoc())
$array[] = $row;
}
return $array;
}
function close(){
$this->sql->close();
}
function castArrayAsString($array){
$types="";
foreach($array as $key => $value) {
if(is_numeric($value)){
if(is_float($value)){
$types.="d";
}else{
$types.="i";
}
}else{
$types.="s";
}
}
return $types;
}
function makeValuesReferenced($arr){
$refs=array();
foreach($arr as $key => $value){
$refs[$key] = &$arr[$key];
}
return $refs;
}
}
$database=new database;
?>
The query that returns 0 result set is doing an 'inner-join', which means that the source table and the target table must share the same value for the columns being linked against in the query (in this case a.id_table2 and b.id). Chances are you don't have any matching values so you are getting a 0 result set. Try a left outer join.
Try the following and see if your results are returned:
"SELECT a.field1, b.field2 FROM table1 AS a INNER JOIN table2 AS b ON a.id_table2=b.id WHERE a.someid = :someId"
$dbo = new Database();
$stmt = $dbo->sql->prepare($sql);
$stmt->bindValue(':someId', $someId, PDO::PARAM_INT);
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
var_dump($row);
}