How to handle result objects from MySQL - php

I am trying to get some relational database handling to work, using PHP and MySQL. To combine output from two different tables, I found some help here on stackoverflow. On of the suggestions was to combine the output in one result object (as I understand it), so the code looks like this:
// Function to read all projects from database
public function get_projects() {
$query = "SELECT pt.*, at.* FROM ed_projects as pt, ed_project_address as at WHERE pt.project_id = at.project_id";
$db_result = $this->db->query($query);
$result_object = $db_result->result();
return $result_object;
}
Where ed_project is the name of the main table, and ed_project_address is the subtable (or whatever it is called), which contains streetname, postal code, city, etc. for each project. The address properties are linked to projects by a project_id.
I can get this to work on the "reading from the database" part, but when I try to use it, I get an error: "Fatal error: Cannot use object of type stdClass as array in (...)". As I am using CodeIgniter, it is passed through 2 additional steps:
Project View Controller:
/* index() - Project view controller
* Handles the showing of the project main page, that is the list of all
* projects found in the database. See also views/projects/index.php.
*/
public function index() {
$data['projects'] = $this->project_model->get_projects();
$data['title'] = 'Ejendomme';
$this->load->view('templates/header', $data);
$this->load->view('projects/index', $data);
$this->load->view('templates/footer');
}
Project View:
<?php foreach ($projects as $projects_item): ?>
<h2><?php echo $projects_item['pt.projects']->project_name ?></h2>
<div class="main"><?php echo $projects_item['at.address_street'] ?></div>
<?php endforeach ?>
The error is in Project View (index.php) on line 3. I have been reading quite a bit on objects in PHP, but the addition of the CodeIgniter framework seems to obscure things just enough for me to not get it :-(. Am I way off here? Or am I just missing the very last bit?

you just made mistake
at your model you returns the object
return $result_object;
but you using it as array at view.
you should use it like this
$projects_item->project_name
If you want to use it as array at your view you should return data from model like this
$result_object = $db_result->result_array();
Also your query will produce error if your both table has same column name. In that case you have to specify which column form which table you want to select.

Related

CodeIgniter - Query array output three times instead one

Output is wrong , i Got three the same comment instead only one.
Can anyone help to make only one comment.
Here my view php code:
$modelid = "5" ;
$query = $this->db->query('SELECT message FROM message WHERE modelid = '.$modelid.' ');
$row = $query->row();
echo $row->message;
and my Table:
http://dev.interactive-creation-works.net/Stack/table.png
The controller:
class Comment extends CI_Controller
{
function index()
{
$data['result'] = $this->db->get('message')->result();
$this->load->view('commentView',$data);
}
function insert()
{
$this->load->model('commentjquery');
echo $this->commentjquery->inserttodb();
}
}
This view should only show one message, even if you do - for whatever reason, correctly or not - get three messages from the query. You may be loading the view three times in your controller. Try adding some static text to the top and bottom of your view, and see if it shows up multiple times.
Edit:
Now that you've posted the controller, I can see that's not the issue. But I notice you're trying to grab the comments from the database twice - once in the controller and once in the model. The one in the controller is actually the wrong way to do it unless you've implemented an ActiveRecord model for your comments, and you're not using the results anyway.
Another thing I noticed just now is that you're calling $query->row() instead of running a foreach over $query->result(). Try this:
foreach($query->result() as $row) {
echo $row->message;
}
Edit 2: Or maybe it is the problem, if the code snippet you posted isn't the entire view, which seems to be the case.
It's really weird that you aren't getting error. It gets weirder when you get three outputs.
Change your query to this.
$query = $this->db->query('SELECT message FROM message WHERE modelid = "'.$modelid.'"');

Cakephp 1.3 HABTM issue! :D

Hey, im having this issue with cakephp, bascially i have a Has And Belongs To Many (HABTM) model relationship.
My models are Categroy and Project
bring all project data is fine, it comes out as [0]['Project'], [1]['Project'] ...etc
but when i use the relationship and pull out projects with certain categories in the categories controller i get these tpye of results [0] (all project data in [0] instead of [0]['Project']), [1] (project data and related model info) this is really messing my code up as i use one element view file to render my projects is there any way to return [0]['Project'] for both project controller and categories controller? thanks Chris
Hi sorry if my example isnt clear
i have projects and categories
when i pull a list of projects from the projects controller from my project model the results i get are in this format
[0]['Project'] = array(data...);
[1]['Project'] = array(data...);
[2]['Project'] = array(data...);
this is how the data is pulled and thats fine for me but when i pull projects per cetegory page using the HABTM relationship in the categories controller from the category model this is how my data is returned
['Project'][0] = array(data...);
['Project'][1] = array(data...);
['Project'][2] = array(data...);
which as you can see is a bit of a strain as i want to keep 1 element view file to display my projects, so far my view file prints data like so
<?php print $project['Project']['title']; ?> //data is returned [x]['Project']
<?php print $project['Feature']['title']; ?>
with the way the HABTM relationship is returning data i would need to do this
<?php print $project['title']; ?> //because data is returned ['Project'][x]
<?php print $project['Feature']['title']; ?>
can anyone help with this? thanks
This has frustrated me too. I like to have one set of elements that can be used for rendering both "primary" find results as well as related find results.
This is the way I currently deal with the differences in formats of results.
When calling find on, say, a "Project" model and wanting to render the related "Task" list, I run the "Task" key of the results through a function on its way into the element like so:
echo $this->element('tasks/index',array(
'data'=>make_primary('Task',$data['Task'])
));
My 'make_primary' function is like so:
function make_primary($alias,$data) {
$d = array();
foreach($data as $item) {
$related = array();
foreach($item as $key => $val) {
if(!is_numeric($key) && is_array($val)) {
$related[$key] = $val;
unset($item[$key]);
}
}
$d[] = array_merge(array($alias=>$item), $related);
}
return $d;
}
This returns a new array as though it was the result of a "primary" find query.

Making anchor load page containing data from referenced row in DB

I'm trying to learn the code igniter library and object oriented PHP in general and have a question.
I've gotten as far as making a page which loads all of the rows from my database and in there, I'm echoing an anchor tag which is a link to the following structure.
echo anchor("videos/video/$row->video_id", $row->video_title);
So, I have a class called Videos which extends the controller, within that class there is index and video, which is being called correctly (when you click on the video title, it sends you to videos/video/5 for example, 5 being the primary key of the table I'm working with.
So basically all I'm trying to do is pass that 5 back to the controller, and then have the particular video page output the particular rows data from the videos table. My function in my controller for video looks like this:
function video()
{
$data['main_content'] = 'video';
$data['video_title'] = 'test';
$this->load->view('includes/template', $data);
}
So ya, basically test should be instead of test, a returned value of a query which says get in the table "videos", the row with the video_id of "5", and make $data['video_title'] equal to value of video_title in database...
Should have this figured out by now but don't, any help would be appreciated!
I don't know if I'm too late but maybe this can solve your problem...
put this in your video() function
data[$query] = $this->db->query("SELECT * FROM videos WHERE video_id = 5");
and then that in your video_view file...
if ($query->num_rows() > 0)
{
$row = $query->row_array();
echo $row['title'];
echo $row['something'];
echo $row['somethingElse'];
}
this is a good resource: http://codeigniter.com/user_guide/database/index.html
hope that helps...
and please someone edit the question because it's too hard to read...
What you need is to understand how the URI Class works
Basically:
$default_url_args = array('video');
$url_args = $this->uri->uri_to_assoc(3,$default_url_args);
$video_UID = $url_args['video'];
and then something like
$the_video = $this->videos_model->get_video_by_UID($video_UID);
You could use the URI Class, or you can do the following:
function video($video_id)
{
$data['main_content'] = $this->videoprovider->get_video( $video_id );
$data['video_title'] = 'test';
$this->load->view('includes/template', $data);
}
In other words, with functions inside classes that extend Controller, you can add parameters to those functions and CI will automatically pass in the URI items in order to those parameters.
function generic_function_in_controller($item1, $item2, ...)
{
// would receive as: http://example.com/controller/generic_function_in_controller/item1/item2
}

How to query a database from view - CodeIgniter

I have query that runs in the controller:
$data['query'] = $this->Member->select_sql($id);
$this->load->view('myform');
and then outputs data in the view:
foreach ($query->result() as $row):
echo $row->post_title;
echo $row->post_user_id;
endforeach;
So this outputs me a list of posts made by a user. Now I would like to run one more query that would for each post loop through my user table and output user information next to each post. (I dont want to select data from a view or joint those 2 tables at this time in MySQL)
Any ideas?
Although it is not a good practice, the "cleanest" approach would be as follows:
Grab the CI instance in the View
Load the model containing your desired data extraction query functions
Run the function from the model in the view
So, in the view:
$CI =& get_instance();
$CI->load->model('modelname');
$result = $CI->modelname->functionname();
var_dump($result);
Tested and working.
Inject the database adapter or appropriate table object into the View.
From your code above, I'd assume this would be
$data['userModel'] = $this->User;
Then use it from there to run your query, e.g.
$user = $userModel->select_sql($row->post_user_id);
Simply
<?php
$qryd='select * from '.$tbname.'';
$queryd = $this->db->query($qryd);
$resultset = $queryd->result_array();
?>

CodeIgniter get_where

I’m attempting to use get_where to grab a list of all database records where the owner is equal to the logged in user.
This is my function in my controller;
function files()
{
$owner = $this->auth->get_user();
$this->db->get_where('files', array('owner =' => '$owner'))->result();
}
And in my view I have the following;
<?php foreach($query->result() as $row): ?>
<span><?=$row->name?></span>
<?php endforeach; ?>
When I try accessing the view, I get the error :
Fatal error: Call to a member function result() on a non-object in /views/account/files.php on line 1.
Wondered if anyone had any ideas of what might be up with this?
Thanks
CodeIgniter is a framework based on MVC principles. As a result, you would usually separate application logic, data abstraction and "output" into their respective areas for CodeIgniter use. In this case: controllers, models and views.
Just for reference, you should usually have you "data" code as a model function, in this case the get_where functionality. I highly suggest you read through the provided User Guide to get to grips with CodeIgniter, it should hold your hand through most steps. See: Table of Contents (top right).
TL;DR
To solve your problem you need to make sure that you pass controller variables through to your view:
function files()
{
$owner = $this->auth->get_user();
$data['files'] = $this->db->get_where('files', array('owner =' => '$owner'))->result();
$this->load->view('name_of_my_view', $data);
}
And then make sure to use the correct variable in your view:
<?php foreach($files as $row): ?>
<span><?=$row['name']; ?></span>
<?php endforeach; ?>
<?php foreach($query->result() as $row): ?>
<span><?=$row->name?></span>
<?php endforeach; ?>
Remove the result function like so.
<?php foreach($query as $row): ?>
<span><?=$row->name?></span>
<?php endforeach; ?>
Btw. It's a much better idea to test the query for a result before you return it.
function files()
{
$owner = $this->auth->get_user();
$query = $this->db->get_where('files', array('owner =' => $owner))->result();
if ($query->num_rows() > 0)
{
return $query->result();
}
return FALSE;
}
public function get_records(){
return $this->db->get_where('table_name', array('column_name' => value))->result();
}
This is how you can return data from database using get_where() method.
All querying should be performed in the Model.
Processing logic in the View should be kept to an absolute minimum. If you need to use some basic looping or conditionals, okay, but nearly all data preparation should be done before the View.
By single quoting your $owner variable, you convert it to a literal string -- in other words, it is rendered as a dollar sign followed by five letters which is certainly not what you want.
The default comparison of codeigniter's where methods is =, so you don't need to declare the equals sign.
I don't know which Auth library you are using, so I'll go out on a limb and assume that get_user() returns an object -- of which you wish to access the id of the current user. This will require ->id chained to the end of the method call to access the id property.
Now, let's re-script your MVC architecture.
The story starts in the controller. You aren't passing any data in, so its duties are:
Load the model (if it isn't already loaded)
Call the model method and pass the owner id as a parameter.
Load the view and pass the model's returned result set as a parameter.
*Notice that there is no querying and no displaying of content.
Controller: (no single-use variables)
public function files() {
$this->load->model('Files_model');
$this->load->view(
'user_files',
['files' => $this->Files_model->Files($this->auth->get_user()->id)]
);
}
Alternatively, you can write your controller with single-use variables if you prefer the declarative benefits / readability.
public function files() {
$this->load->model('Files_model');
$userId = $this->auth->get_user()->id;
$data['files'] = $this->Files_model->Files($userId);
$this->load->view('user_files', $data);
}
Model: (parameters are passed-in, result sets are returned)
public function Files($userId) {
return $this->db->get_where('files', ['owner' => $userId])->result();
}
In the above snippet, the generated query will be:
SELECT * FROM files WHERE owner = $userId
The result set (assuming the query suits the db table schema) will be an empty array if no qualifying results or an indexed array of objects. Either way, the return value will be an array.
In the final step, the view will receive the populated result set as $files (the variable is named by the associative first-level key that was declared in the view loading method).
View:
<?php
foreach ($files as $file) {
echo "<span>{$file->name}</span>";
}
The { and } are not essential, I just prefer it for readability in my IDE.
To sum it all up, the data flows like this:
Controller -> Model -> Controller -> View
Only the model does database interactions.
Only the view prints to screen.

Categories