Changing database results in model as object - php

In past Codeigniter projects, I have always used $query->result_array() instead of $query->result()
For example, as an array, I would have the following in a model:
$this->db->select('id, username');
$this->db->from('users');
$query = $this->db->get();
$result = array();
foreach ($query->result_array() as $row)
{
$id = $row['id'];
$result[$id]['id'] = $row['id'];
$result[$id]['username'] = strtolower($row['username']);
)
return $result;
It can get really messy with more records and I have to add all of the fields even if I just need to perform operations on only one of them.
Now, for my current project, I am trying to just $query->result(), which is just an array of objects, but I'm not sure how to perform operations on them and return the results.
For example, if I'm using $query->result() and I want to make every username lowercase (strtolower), how would I perform those changes in the model?

The answer to your example and comment:
$results = $query->result();
foreach($results as $result){
$result->username = strtolower($result->username);
}
return $results;

foreach($query->result() as $row){
$username_lower = strtolower($row->username);
//if you want to actually update the record in the db
$this->db->where('id',$row->id);
$this->db->update('users', array('username' => $row->username));
}

Related

PHP PDO FetchAll vs Fetch

I believe I am using the PDO fetch functions completely wrong. Here is what I am trying to do:
Query a row, get the results, use a helper function to process the results into an array.
Query
function userName($db){
$q = $db->prepare("SELECT id, name FROM users WHERE id = :user");
$q->bindParam(":user", $user);
$q->execute();
$qr = $q->fetchAll(PDO::FETCH_ASSOC);
if ($qr->rowCount() > 0){
foreach($qr as $row){
$names[$row['id']] = buildArray($row);
}
return $names;
}
}
My custom array building function
function buildArray($row){
$usernames = array();
if(isset($row['id'])) $usernames['id'] = $row['id'];
if(isset($row['name'])) $usernames['name'] = $row['name'];
}
I'm actually getting exactly what I want from this, but when I echo inbetween I see that things are looping 3 times instead of once. I think I am misusing fetchAll.
Any help appreciated
If you're going to build a new array, there's not much point in having fetchAll() build an array. Write your own fetch() loop:
function userName($db){
$q = $db->prepare("SELECT id, name FROM users WHERE id = :user");
$q->bindParam(":user", $user);
$q->execute();
$names = array();
while ($row = $q->fetch(PDO::FETCH_ASSOC)) {
$names[$row['id']] = $row;
}
return $names;
}
There's also no need for buildArray(), since $row is already the associative array you want.

Selecting records from a database table in PHP using CodeIgniter and pass to a view

I'm making a query in PHP using CodeIgniter to get the data that I wanted from a database. To be able to get all values for a specific column, I stored it into an array and passed it into a view. But I can do it only for one column.
Here's my code:
$query = $this->db->query('SELECT name, description FROM module');
$result = $query->result_array();
foreach ($result as $key => $rowdata) {
$resultdata['values'][$key] = $rowdata['name'];
}
$this->load->view('myview', $resultdata);
With this scenario I can get all name from the module table. But my problem is, I also wanted to get all the description in the module table, but I don't know how can I implement it and be able to pass it into the view. Hope someone could help me with this. Thanks!
Your not using the MVC pattern!
First you should write your query in a model!
Then load it in your controller like this
$this->load->model('ModelName');
Then call the funcion to retreive the data
$data = $this->modelname->functionToRetreiveData();
Then loop through data with foreach
$dataToView = array();
foreach($data as $key=>$row)
{
$dataToView['something'][$key]['value'] = $row->name_of_column;
}
And pass the array to the view $this->load->view('someview',$dataToView);
Then in the view
foreach($value as $val):
<p><?php echo $val['name']?><p>
endforeach
hi in you way you will do loop twice in controller and then in view to print it check this out
//in controller
$query = $this->db->query('SELECT name,description FROM module');
$resultdata['results'] = $query->result_array();
$this->load->view('myview',$resultdata);
myview.php
foreach($results as $result)
{
echo $result['name'],' ',$result['description'];
}
$query = $this->db->query('SELECT name,description FROM module');
$result = $query->result_array();
foreach($result as $rowdata){
$resultdata['values'][] = $rowdata;
}
$this->load->view('myview',$resultdata);
Try in view:
print_r($values);
You will probably have:
$result[0]['name'], $result[0]['description'] ...
$this->load->database();
$this->db->select('employee');
$query = $this->db->get();
return $query;
foreach ($query as $row) {
print $row->'Name';
.
.
.
print $row->'Address';
}

getting a value from a resultset with Codeigniter

In my model I have this snippet
$this->db->select('*');
$this->db->from('User');
$this->db->where('email', $mail);
$query = $this->db->get();
return $query;
As far as I know, $query is an array (a set of results), I want to retrieve an specific value of a field in that array to return it or to assign it to another variable, the question is HOW?
I'd like to do something like this
$value = $query['first_field_of_resultset'];
return $value;
extending Johns answer, you need to cover yourself in case nothing comes back
so in your model method:
// make sure we have a result
if ( $query->num_rows() == 1 )
{
// assign the result
$user = $query->row();
// pull out the field you want
$value = $user->first_field_of_resultset;
// return it
return $value ;
}
else { return FALSE; }
Then in your controller, say if the model is called user_model
if(! $value = $this->user_model->getUser($email) )
{
// boo hoo no results
}
else
{
// success
}
And of course this assumes you have run $email through CI form validation to make sure it is a valid email -- before sending to your database.
There's a bunch of different ways to get the results. Here's one:
$user = $query->row();
echo $user->first_field_of_resultset;
If you prefer arrays:
$user = $query->row_array();
echo $user['first_field_of_resultset'];
If you want the first row you can do:
$row = $query->first_row();
But I don't know why you are retreaving all fields if you only need just one column:
$this->db->select('user.the_column_to_select');
$query is an object. So in order to get the results as an array you need to do the following.
$result = $query->result_array();
return $result[0];
You can try this also:
$email = $this->db->select('email')->from('users')->where(array(
'userID' => $userID))->limit(1)->get()->row('email');
// $email will either be the email address you're looking for or FALSE

how do we use mysqli properly to fetch all the records from table?

I am getting only one row, can someone please tell me how to get all the data from the table column of my database table ?
public function getCategories(){
$result = $this->db->query('SELECT * FROM newscat');
$rows = array();
while($row = $result->fetch_assoc()){
$rows[] = $row;
return $rows;
}
}
You're returning from within the loop. That will break it in the first round.
return outside the loop.
do the minor change
public function getCategories(){
$result = $this->db->query('SELECT * FROM newscat');
$rows = array();
while($row = $result->fetch_assoc()){
$rows[] = $row;
}
return $rows;
}
Your problem is the return $rows;. It should reside after the while. The thing is that it will enter the while, put the first row in the array, and then immediately return it. What you want is to let the while do its thing, and after the it finished, return the array.
If you are using mysqli.
Then you can use its apiFfetch_all to get all the rows at once.
For example :
$array=$result->fetch_all(MYSQLI_ASSOC);
The above code will get all associated rows in the corresponding array.

MultiDimensional Arrays

In Codeigniter, I have the following model
function get_item_history($id)
{
//from metadata_history get item_id and corresponding metadata
$this->db->from('metadata_history')->where(array('id'=>$id, 'current_revision'=> "TRUE"));
$query = $this->db->get();
$result = $query->result_array(); //store this in an array
// loop through the array
foreach( $result as $key => $row )
{
$array = array('item_id'=>$row['item_id'], 'current_revision'=> "TRUE");
$this->db->from('history')->where($array);
$query = $this->db->get();
$row['items'] = $query->result_array(); //
$result[$key] = $row;
}
return $result;
}
The problem is that this results in multiple queries to the SQL table increasing the execution time significantly (pagination is not an option)
I want to be able to pass the first query results to the second query as an array, so that I would have only a single go at the database, then rebuild an array from the results.
How should I rewrite this code (the second part)? Will it be faster (I suppose so)?
EDIT
Rebuilding the array from the results is what is flummoxing me.
http://www.phpbuilder.com/board/showthread.php?t=10373847
this is what I probably want, but am failing the jump
You can use inner query here. It is ideal situation for that -
function get_item_history($id)
{
// Here the above requirement can be achieved in a single query.
$sql = "select * from history h
where h.item_id IN (select item_id from metadata_history mh where mh.id = $id
AND mh.current_revision = TRUE) AND h.current_revision = TRUE";
$result = $this->db->query($sql);
//Return whichever column of result you want to return or process result if you want.
$result;
}
You should use JOINs to do this. It'll offload the execution of the query to the server. I can't give you too much more detail without knowing how your database is structured, but check out the docs on JOINs:
http://dev.mysql.com/doc/refman/5.0/en/join.html
http://www.webdesign.org/web-programming/php/mysql-join-tutorial.14876.html
http://www.keithjbrown.co.uk/vworks/mysql/mysql_p5.php
Another option would be to do your wheres in the loop and move the query executation outside of the foreach:
// loop through the array
foreach( $result as $key => $row )
{
$array = array('item_id'=>$row['item_id'], 'current_revision'=> "TRUE");
$this->db->or_where($array);
}
$query = $this->db->get();
$row['items'] = $query->result_array(); //
$result[$key] = $row;
OK this took some work, and I also had to do some adjustments in my view
So the problem can be broken down into two main components
1) Pass the results of the first query as an array to the second one using where_in
2) Reorder/regroup the results of the first array by item_id
My earlier code was doing the second component implicitly
So here is what I did (limits, offsets, ordering have been cut out to improve readablity)
function get_item_history($id)
{
//from metadata_history get item_id and corresponding metadata
$this->db->from('metadata_history')->where(array('id'=>$id, 'current_revision'=> "TRUE"));
$query = $this->db->get();
$result_query1 = $query->result_array(); //store this in an array
foreach ($result_query1 as $key-> $row){
$result[$row['item_id']]['meta_info'] = $row; //the first query contains meta info, that must be passed to the view
$selected_id_array[] = $row['item_id']; //Create a array to pass on to the next query
$result[$row['item_id']]['items'] = array(); //declare an array which will hold the results of second query later
}
$this->db->select('h.*');
$this->db->from('history h');
$this->db->where_in('h.item_id', $selected_id_array);
$this->db->where(array('h.current_revision' => 'TRUE'));
$query = $this->db->get();
$row = $query->result_array();
foreach ($row as $key => $datarow) {
$result[$datarow['item_id']]['items'][] = $datarow; //populate the array we declared earlier with results from second query
}
return $result; // Now this variable holds an array which is indexed by item id and contains the results of second query 'grouped' by item_id
}
So the number of queries have been cut from ~10 to 2.
On my local machine this saves ~50 msec/page, though I am not sure how this will do for larger databases.

Categories