I think PDO fetch() and fetchColumn() block each other - mysql

So I was experimenting with PDO queries. Take a look at this snippet:
1. $rows = $stmt->fetchColumn();
2. echo $rows;
3. $row = $stmt->fetch();
4. print_r($row);
This is just an observation... not sure how true tho!
Line 2 is executed and returns the number of rows (in my case 1 because I was just authenticating a user).
Line 4 doesn't return anything.
If you flipped the order:
1. $row = $stmt->fetch();
2. print_r($row);
3. $rows = $stmt->fetchColumn();
4. echo $rows;
The array from line 2 is printed but line 4 returns nothing! Is this proper behavior?
Anyways, how do I achieve the following result?
if ($stmt->fetchColumn() == 1) {
$row = $stmt->fetch();
print_r($row);
} else {
echo '<div class="error-message">Verify Your Credentials</div>';
}

It is proper behavior, fetchColumn fetches one column. You cant fetch it twice. You can use:
/* fetches row from the result, if theres no row in the result, fetch returns false */
$row = $stmt->fetch();
/* compare if $row is true (in PHP, "boolean value" of unempty array is true) */
if ( $row ) {
print_r($row);
} else {
echo '<div class="error-message">Verify Your Credentials</div>';
}

this answer might help you PDO fetch one column from table into 1-dimensional array
fetchColumn only returns a single result but you can flatten your result in different ways using the pdo::fetch methods, you should look them up and they will quickly and simply sort out your results. Try this for some more reading also https://phpdelusions.net/pdo/fetch_modes

Related

Codeigniter Array values Assign to Variables

I have following data array returned by Item_model. This array included some values of MySQL tables columns such as 'r_qty' and 'ap_qty'.
$this->data['issueData']=$this->Item_model->ItemRequestfromHDData($id);
Item_model
function ItemRequestfromHDData($id)
{
$this->db->select('store_update_stock.*,store_update_stock_details.*,tbl_user.username,store_item.*,
sum(qty) as avqty, sum(store_update_stock_details.r_qty) as r_qty,
sum(store_update_stock_details.ap_qty) as ap_qty');
$this->db->from('store_update_stock_details');
$this->db->join('store_update_stock', 'store_update_stock.update_stock_id=store_update_stock_details.update_stock_id');
$this->db->join('tbl_user', 'store_update_stock.supplier=tbl_user.userId');
$this->db->join('store_item', 'store_update_stock_details.item=store_item.item_id', 'left');
$this->db->where(array('store_update_stock.update_stock_id' => $id, 'store_update_stock_details.status' => 1));
$this->db->group_by('store_item.item_id');
$q = $this->db->get();
if ($q->num_rows() > 0) {
return $q->result();
}
return false;
}
I want to assign these two columns / values to variables. I tried following assignments.
$r_qty = $data['r_qty'];
$ap_qty = $data['ap_qty'];
but didn't get the expected result. What may be going wrong ? Can anyone help ?
As per codeigniter documentation,
result()
This method returns the query result as an array of objects, or an
empty array on failure.
Typically you’ll use this in a foreach loop, like this:
$query = $this->db->query("YOUR Q enter code here QUERY");
foreach ($query->result() as $row)
{
echo $row->title;
echo $row->name;
echo $row->body;
}
So, your code should be
foreach ($this->data['issueData'] as $data)
{
$r_qty = $data->r_qty;
$ap_qty = $data->ap_qty;
}

MySQL pdo select single column with limit but return one row

I'm trying to get the last 3 records from my table + only the titles column but I get only one result.
$query = $connect->prepare("SELECT title FROM tutorials LIMIT 3");
$query->execute();
$result = $query->fetch(PDO::FETCH_ASSOC);
foreach($result as $key => $value) { echo $value; }
Is working if I use fetchAll but in my case I don't need all the columns, just the only one(title) so there is no sense using fetchall but why is returning only one row?
fetch retrieves one row, or it returns FALSE if there is no row to fetch. (We could do the processing in a loop, and fetch each "next row", until fetch returns FALSE.
$query->execute();
while ( $row = $query->fetch(PDO::FETCH_ASSOC) ) {
echo $row['title'];
}
There's only one column in the resultset. It seems like we are confused about fetch and fetchAll.
http://php.net/manual/en/pdostatement.fetch.php
http://php.net/manual/en/pdostatement.fetchall.php
If we use fetchAll to retrieve all of the rows, we get an array back, each element in the array is a row from the resultset.
$query->execute();
if( $rs = $query->fetchAll(PDO::FETCH_ASSOC) ) {
foreach($rs as $row) {
echo $row['title'];
}
}
http://php.net/manual/en/pdostatement.fetch.php says:
PDOStatement::fetch — Fetches the next row from a result set
It only fetches one row each time you call fetch(). You either need to call it in a loop until it reaches the end of your result set, or else use fetchAll().
It sounds like you are mixing up the terms "row" and "column" somehow.

mySQL query for building dynamically populated model

I have some code below which demonstrates a hard-coded example of what I would like to accomplish dynamically.
At a high level, I wish to do something like select * from view_data_$app_state and then get all of the data from that views table into my mustache templates dynamically.
The code I currently must use to group multiple rows of data for a specific column along with the views data is:
<?php
error_reporting(E_ALL);
class Example {
function __construct(){
try {
$this->db = new PDO('mysql:host=localhost;dbname=Example', 'root','drowssap');
}
catch (PDOException $e) {
print($e->getMessage());
die();
}
}
function __destruct(){
$this->db = null;
}
function string_to_array($links_string){
return explode(",", $links_string);
}
function get_view_data(){
$q = $this->db->prepare('select *, GROUP_CONCAT(`links`) as "links" from `view_data_global` ');
$q->execute();
$result = $q->fetchAll(PDO::FETCH_ASSOC);
return $result;
}
}
$Example = new Example();
$result = $Example->get_view_data();
$result[0]["links"] = $Example->string_to_array($result[0]["links"]);
echo json_encode($result);
This gives me the perfect object while
GROUP_CONCAT seems to be doing the trick this way, however I MUST know the column name that will contain multiple rows before writing the query. I am trying to figure out an approach for this and wish to make a custom query + code example that will transform cols with multiple rows of null null and not empty data into an array like above - but return the data.. again like the code above.
Below is an output of the actual data:
[{"id":"1","title":"This is the title test","links":["main","about","store"]}];
How can I replicate this process dynamically on each view table?
Thank you so much SO!
You can use PDOStatement::fetch to retrieve your results, with fetch_style set to PDO::FETCH_ASSOC (some other values will also provide the same information). In this case, the result set will be array indexed by column name. You can access this information with foreach (array_expression as $key => $value)
See the documentation for additional information.

PHP PDO succinct mySQL SELECT object

Using PDO I have built a succinct object for retrieving rows from a database as a PHP object with the first column value being the name and the second column value being the desired value.
$sql = "SELECT * FROM `site`"; $site = array();
foreach($sodb->query($sql) as $sitefield){
$site[$sitefield['name']] = $sitefield['value'];
}
I now want to apply it to a function with 2 parameters, the first containing the table and the second containing any where clauses to then produce the same result.
function select($table,$condition){
$sql = "SELECT * FROM `$table`";
if($condition){
$sql .= " WHERE $condition";
}
foreach($sodb->query($sql) as $field){
return $table[$field['name']] = $field['value'];
}
}
The idea that this could be called something like this:
<?php select("options","class = 'apples'");?>
and then be used on page in the same format as the first method.
<?php echo $option['green'];?>
Giving me the value of the column named value that is in the same row as the value called 'green' in the column named field.
The problem of course is that the function will not return the foreach data like that. That is that this bit:
foreach($sodb->query($sql) as $field){
return $table[$field['name']] = $field['value'];
}
cannot return data like that.
Is there a way to make it?
Well, this:
$sql = "SELECT * FROM `site`"; $site = array();
foreach($sodb->query($sql) as $sitefield){
$site[$sitefield['name']] = $sitefield['value'];
}
Can easily become this:
$sql = "SELECT * FROM `site`";
$site = array();
foreach( $sodb->query($sql) as $row )
{
$site[] = $row;
}
print_r($site);
// or, where 0 is the index you want, etc.
echo $site[0]['name'];
So, you should be able to get a map of all of your columns into the multidimensional array $site.
Also, don't forget to sanitize your inputs before you dump them right into that query. One of the benefits of PDO is using placeholders to protect yourself from malicious users.

Codeigniter - Perform action if database query returns no results

How can I return a value of 'no data found' if my query returns no results???
This is my code:
function getTerms($letter) {
$this->db->select('term, definition');
$this->db->from('glossary');
$this->db->where(array('letter' => $letter));
$query = $this->db->get();
foreach ($query->result() as $row) {
$data[] = array(
'term' => $row->term,
'definition' => $row->definition
);
}
return $data;
}
It currently returns the $data variable even if the query returns no results which is giving me php errors. How can I check that there are results before returning the $data array.
Simply check that the query returns at least one row:
if ($query->num_rows() > 0) {
// query returned results
} else {
// query returned no results
}
Read more in the docs
It currently returns the $data variable even if the query returns no results which is giving me php errors.
It's a good habit to initialize the array that you intend to build:
$data = array();
// Loop through possible results, adding to $data
If there are no results you'll get an empty array returned, then check that in your controller.
This way, at least the variable is defined and you won't get notices.
What about to give initial empty array value for $data
Just put
$data = array();
before foreach
<?php
return is_array($data) ? $data : array();
}