So I'm having this problem, it should be pretty simple, but I don't know why I can't figure it out. I"m new to the whole idea of MVC, and I'm trying to pass a database query from my controller into a view and display the results in the view. The way I'm doing it now says "undefined variable, sql" when I load the view. This is what I have:
CONTROLLER
function make_login()
{
//Select list of departments for dropdown
$this->load->database();
$sql = $this->db->query('SELECT departmentName FROM department ORDER BY departmentName ASC');
$this->load->view('siteheader.php');
$this->load->view('makelogin.php', $sql->result_array());
$this->load->view('sitefooter.php');
}
VIEW
<?php
foreach($sql->result_array() as $row)
{
echo $row['departmentName'];
}
?>
(If I just echo it out in the controller, it displays the results)
Any help would be awesome...
THANKS!
few tips ~
your make_login should be in a model. your controller will look something like this:
function make_login
{
$this->load->model('login_model'); // whatever you call it
$data['departments'] = $this->login_model->get_departments();
/* note - you don't need to have the extension when it's a php file */
$this->load->view('siteheader');
$this->load->view('makelogin', $data);
$this->load->view('sitefooter');
}
now in your model, have something like:
function get_departments()
{
$sql = $this->db->query('SELECT departmentName FROM department ORDER BY departmentName ASC');
return $sql->result();
/* you simply return the results as an object
* also note you can use the ActiveRecord class for this...might make it easier
*/
}
and finally, your view:
<?php
foreach($departments as $store)
{
echo $store->name . '<br />'; // your fields/whatever you want to output.
}
?>
The SQL query should be done in the model.
Cheap mnemonic device: the D in model = database.
In the Controller, you assign part of the $data array to the results of the query:
$this->load->model('blog_model');
$data['posts'] = $this->blog_model->getPosts();
// Load the view with the data
$this->load->view('blog', $data);
In the Model, you do the actual query:
public function getPosts()
{
// Method chaining supported in PHP 5
$this->db->select('*')->from('posts');
// Assign the query object to a variable
$query = $this->db->get();
// We don't want to return an empty result, so let's handle that error somehow
if (!$query->num_rows() > 0) {
die("There are no posts in the database.");
}
// Make a new array for the posts
$posts = array();
// For the purposes of this example, we'll only return the title
foreach ($query->result() as $row) {
$posts[$row->id] = $row->title;
}
// Pass the result back to the controller
return $posts;
}
Now, in the view, each element of $data will be its own variable:
<div class="post">
<?php foreach ($posts as $id => $title) : ?>
<h1 class="post-title"><?php echo $title; ?> (ID: <?php echo $id; ?>)</h1>
<p class="post-content">
.......
</p>
<?php endforeach; ?>
</div>
That's it!
It seems that either CI is confusing you or you are also new to PHP. They are just functions so you can't pass variables like that.
When passing an associative array it will take the key and make that into a variable with the value in the array, using native PHP functions. What Ross said is exactly what you are supposed to do.
Model: all database stuff
Controller: uses models to pass variables to views
View: outputs the variables (a view should never have any sql in it)
Also note that result and result_array have the same data but result returns objects and result_array returns associative arrays.
foreach($array as $row)
{
echo $row['departmentName'];
}
?>
You need to pass the $array in.
I am not sure what ->load->view() does and how it treats the incoming parameters.
Related
I'm new to CodeIgniter.
I have two functions in my Controller. In one with post method I create data array and then put that array to session. In another function I need another values, like title or date (because in session I only have ID values), so I send ID values to Model functions and then I load view with data I need. Then in view I print out the data I need. But I get an error saying
Message: Undefined index: DCM_TITLE
Controller function code:
public function visi_registravimas(){
$this->output->enable_profiler(TRUE);
$DCM_ID = $_SESSION['DCM_ID'];
$PRD_ID = $_SESSION['PRD_ID'];
$result['documents'] = $this->Skaitikliu_registras_model->setDocument($DCM_ID);
$result['periods'] = $this->Skaitikliu_registras_model->setPeriod($PRD_ID);
$this->load->view('skaitikliu_registras/visi_registravimas_view',$result);
}
model:
public function setDocument($DCM_ID){
$query = $this->db->query("SELECT * FROM RA_DOCUMENT WHERE DCM_ID='$DCM_ID'");
return $query;
}
public function setPeriod($PRD_ID){
$query = $this->db->query("SELECT * FROM RA_PERIOD WHERE PRD_ID='$PRD_ID'");
return $query;
}
And this is how I print data in view:
<body>
<?php $this->load->view('navbar_view'); ?>
<?php foreach($documents as $document) : ?>
<?php echo $document['DCM_TITLE']; ?>
<?php endforeach ?>
</body>
Change this in Model Query:
return $query;
return $query->result_array();
result_array() returns the query result as a pure array Format.
Note:- For More Information regarding this
https://codeigniter.com/userguide3/database/results.html
To expand on the #KUMAR answer I would also advise to start using the query builder instead of writing the queries yourself.
This is a good practice so if in any case you change your database from MYSQL to postgresql or any other database engine you don't need to change anything about your models.
In this case your model functions would look like this:
public function setDocument($DCM_ID){
$q = $this->db->where('DCM_ID', $DCM_ID)->get('RA_DOCUMENT');
return $q->result_array();
}
public function setPeriod($PRD_ID){
$q = $this->db->where('PRD_ID', $PRD_ID)->get('RA_PERIOD');
return $q->result_array();
}
This way you get cleaner code and code that can be maintained for longer.
I've been using 2 methods to render data.
The first one:
function name($id,$name){
return '<div id="'.$id.'">'.$name.'</div>';
}
echo implode($pdo->query("SELECT id,name FROM user")->fetchAll(PDO::FETCH_FUNC,'name'));
The second one:
$users = $pdo->query("SELECT id,name FROM user")->fetchAll(PDO::FETCH_OBJ);
foreach($users as $user){
echo name($user->id,$user->name);
}
I don't really understand how PDO::FETCH_FUNC works. I already tried to figure it out. However, this is not so well-documented.
Could anybody please explain this fetch mode? And also, which one performs better? Thank you.
Both methods are wrong and you have to learn how to use templates and how to separate business logic from presentation logic.
$users = $pdo->query("SELECT id,name FROM user")->fetchAll(PDO::FETCH_OBJ);
tpl::assign('users', $users);
is ALL the code for the business logic part.
then in template
<?php foreach $users as $row): ?>
<div id="<?=$row->id?>"><?=$row->name?></div>
<?php endforeach ?>
Frankly, your business logic should contain not a trace of HTML while presentation logic should contain not a single database call.
Here is an example:
$stmt = $pdo->query('SELECT id, name FROM user');
$data = $stmt->fetchAll(PDO::FETCH_FUNC, array('Foo', 'name'));
Class Foo {
public static function name($id, $name) {
return '<div id="'.$id.'">'.$name.'</div>';
}
}
So basically FETCH_FUNC mode fetches records to user defined function. This is useful because you can manipulate the result.
Use static method if you are not passing in an object of the class. You can just pass in an object and not use static method just the way #Barmar noted in comments.
I have a custom joomla MVC component.
The component has a table of items,
and a table of bids to deliver those items.
I have figured out how to display a list the relevant 'bids' on the view for an 'item' by adding this to the item model:
public function getBidsById($id) {
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query
->select('*')
->from('#__entrusters_bids ')
->where('item_id = ' . $id);
$db->setQuery($query);
$db->query();
return $db->loadObjectList();
}
This to the views/item/view.html.php:
$model = $this->getModel('Item', 'EntrustersModel');
$itemID = jRequest::getVar('id');
$bidsOnItem = $model->getBidsById($itemID);
$this->bidsOnItem = $bidsOnItem;
And e.g. this to the views/item/tmpl/default.php:
var_dump($this->items_by_id);
That all works fine.
Here's the actual question:
Now i need to show a COUNT of the bids on the LIST view (items - with an s) within each row of the foreach.
What is the BEST way of achieving this? I have tried adding the same to the items model and views/items/view.html.php, then I attempted something like this in the list:
<ul>
<?php foreach ($this->items as $item) : ?>
<li>Item stuff about the item. This item has <?php echo count($item->bidsOnItem); ?> bids</li>
<?php endforeach; ?>
</ul>
But that just returns 0 - not the count of bids on each item in the list. Grateful for help from the MVC experts out there.
You've gone and got yourself mixed up there. For a start to assign variables to a template, you need to do the following:
$bar = 'bar';
$this->assignRef('foo', $bar);
Also, your query returns a list of items rather than a multi-dimensional array of items. To get the count of bids by item, you need to run a separate query for each item
Eg.
Model
class SomethingModelTest extends JModelLegacy {
function getItemList() {
// query goes here
// return results
}
function getBidsByItemId($itemId) {
// query goes here
// return results
}
}
View
class SomethingViewTest extends LegacyView {
public function display() {
$items = $this->get('ItemList');
foreach ($items as &$item) {
$item->bids = $this->getModel()->getBidsByItemId($item->itemId);
}
$this->assignRef('items', $items);
parent::display();
}
}
And then use your for loop and instead of print count($blah); just use print $item->bids.
I have rephrased this question (hopefully in a more useful way) here: Add a count of related data to each item in a joomla MVC list view
I have a query in CodeIgniter model, like:
$query = $this->db->get('subscriber');
The above query is returning 474 rows as a result.
Now I want to iterate these value in my view in table format so I am storing the value in a PHP native session, like:
$_SESSION['list'] = $query;
But when I am iterating over this loop in view, I am not getting the desired result.
The value of $_SESSION['conn_id'] is '0'
The value of $_SESSION['result_id'] is '0'
The value of $_SESSION['result_array'] is 'Array'
The value of $_SESSION['result_object'] is 'Array'
The value of $_SESSION['custom_result_object'] is 'Array'
The value of $_SESSION['current_row'] is '0'
The value of $_SESSION['num_rows'] is '474'
The value of $_SESSION['row_data'] is ''
While using
foreach($_SESSION['list'] as $key=>$value)
{
echo 'The value of $_SESSION['."'".$key."'".'] is '."'".$value."'".' <br />';
}
I know this is not the method to do this. How can I access the quesryset result in CodeIgniter view?
Can we use the queryset data directly or not?
What you would typically do is something like this
//model.php
class Subsrciber_Model extends CI_Model
{
public function get_subscribers()
{
return $this->db->get('subscriber');
}
}
//controller.php
class Subscribers extends CI_Controller
{
public function subscribers()
{
$this->model->load('Subscriber_Model');
$data = $this->Subscriber_model->get_subscribers();
$this->load->view('view', $data);
}
}
//view.php
<div>
<?php foreach ($data->result() as $row): ?>
<p><?=$row->conn_id?></p>
<? endforeach; ?>
</div>
Try this:
$query = $this->db->get('subscriber')->result_array();
Are you sure that an array is being returned from your query? From the output of your SESSION it looks like you are treating an object like an array.
Try doing this in your model
$query = $this->db->get('subscriber')->result_array();
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.