This question already has answers here:
"Notice: Undefined variable", "Notice: Undefined index", "Warning: Undefined array key", and "Notice: Undefined offset" using PHP
(29 answers)
Closed 9 years ago.
First time!
I'm learning Code Igniter, and as my first project I'm rewriting an existing site in CI.
On the existing site, all pages, dynamic or static, use a PHP include to load sidebar.php which is populated from the categories table in the database.
<div id="sidebar">
<?php
$result = mysql_query('SELECT category_id, name, url FROM categories ORDER BY category_id ASC');
while ($row = mysql_fetch_array($result)) {
$name=$row['name'];
$url=$row['url'];
print "<p>$name</p>";
}
?>
</div>
So now I've started in CI, I figured that the way to go was to make a sidebar model with the database call, a sidebar controller, a sidebar view, and then to load this view in the default page controller.
So, in /application/models I've got sidebar_model.php
<?php
class Sidebar_model extends CI_Model {
public function __construct()
{
$this->load->database();
}
public function get_categories()
{
$query = $this->db->get('categories');
return $query->result();
}
}
Then in applications/controllers there is sidebar.php
<?php
class Sidebar extends CI_Controller {
public function __construct()
{
parent::__construct();
}
public function index()
{
$this->load->model('sidebar_model');
$data['result'] = $this->sidebar_model->get_categories();
$this->load->view('templates/sidebar_view', $data);
}
}
And then in applications/views/templates there is sidebar_view.php
<div id="sidebar">
<?php foreach($result as $row): ?>
<p><?php echo $row['name'] ?></p>
<?php endforeach ?>
</div>
This is called from my main page controller -
<?php
class Pages extends CI_Controller {
public function view($page = 'home')
{
if ( ! file_exists('application/views/pages/'.$page.'.php'))
{
// Whoops, we don't have a page for that!
show_404();
}
$data['title'] = ucfirst($page); // Capitalize the first letter
$this->load->view('templates/header', $data);
$this->load->view('pages/'.$page, $data);
$this->load->view('templates/sidebar_view', $data);
$this->load->view('templates/footer', $data);
}
}
The trouble I'm having is that whilst the page controller is obviously loading the sidebar view (the box is showing with the correct CSS styling) it's throwing up PHP errors.
A PHP Error was encountered
Severity: Notice
Message: Undefined variable: result
Filename: templates/sidebar_view.php
Line Number: 2
Can anyone point me in the right direction here? Whilst just using a php include for the sidebar would be quick and easy, it doesn't seem like the MVC way of doing things.
Apologies for the lengthy post, and thanks in advance!
you are loading Pages controller and calling a view of Sidebar controller the variable $result gets data when Sidebar controller will load and you are loading Pages controller you have to load model of sidebar in pages controller
like
class Pages extends CI_Controller {
public function view($page = 'home')
{
$this->load->model('sidebar_model');
$data['result'] = $this->sidebar_model->get_categories();
if ( ! file_exists('application/views/pages/'.$page.'.php'))
{
// Whoops, we don't have a page for that!
show_404();
}
$data['title'] = ucfirst($page); // Capitalize the first letter
$this->load->view('templates/header', $data);
$this->load->view('pages/'.$page, $data);
$this->load->view('templates/sidebar_view', $data);
$this->load->view('templates/footer', $data);
}
}
if you need sidebar for your all pages you can do in a good way like this first you need to extend MY_Controller and then extend you all controllers with MY_Controller
MY_Controller put in application core directory
<?
MY_Controller extends CI_Controller{
public $_sidebar = '';
public function __construct() {
parent::__construct();
$this->_sidebar = $this->sidebar();
}
private function sidebar(){
$this->load->model('sidebar_model');
$data['result'] = $this->sidebar_model->get_categories();
return $this->load->view('templates/sidebar_view', $data,TRUE);
}
}
now your page Controller
<?php
class Pages extends MY_Controller {
public function __construct() {
parent::__construct();
}
public function view($page = 'home')
{
if ( ! file_exists('application/views/pages/'.$page.'.php'))
{
// Whoops, we don't have a page for that!
show_404();
}
$data['title'] = ucfirst($page); // Capitalize the first letter
$data['sidebar'] = $this->_sidebar;
$this->load->view('templates/header', $data);
$this->load->view('pages/'.$page, $data);
$this->load->view('templates/footer', $data);
}
}
now you have sidebar as variable and it will be available to your controllers every time just define sidebar in you main template html any where you want
Your $data array in the Pages controller needs to have a "results" entry. Values in the array passed to a view are converted to local variables for use in the view. You do it correctly in the Sidebar controller (which you don't really need).
Related
I am trying to make page info rendered from database.
I have database:
page | title | description
main | Welcome | This is the main page
Controller to get page data and render View
class Main extends CI_Controller {
function __construct()
{
parent::__construct();
$this->load->helper(array('url', 'html', 'assets'));
$this->load->model('pages_model');
}
public function index() {
// This is a page variable
// in this case it will be "main"
$page = strtolower(basename(__FILE__, '.php'));
// Page data
$data['pg'] = $this->pages_model->page();
// Render
$this->load->view('templates/header', $data);
$this->load->view('pages/main', $data);
$this->load->view('templates/footer', $data);
}
}
Then Model where i try to fetch data for specific page
Class Pages_model extends CI_Model {
function page()
{
$query = $this->db->select('*')->where('page', $page)->get('pages');
return $query->result();
}
}
But i get error "undefined variable $page in model". How can i fix it?
You missed to pass "$page" in model. update your code as below:
In controller:
// Page data
$data['pg'] = $this->pages_model->page($page);
And in model
function page($page)
I'm with a doubt at this post:
http://www.ahowto.net/php/easily-integrateload-phpexcel-into-codeigniter-framework/
I've done up to libraries part (Excel.php).
But in the tutorial, where it starts Example Usage, where exactly I need to put all that code? In a new controller? Here in my project I tried to create a new Controller called Report. In report I've this code:
public function readReport() {
$this->load->library('excel');
$this->excel=PHPExcel_IOFactory::load(APPPATH."/third_party/teste.xlsx");
$this->excel->setActiveSheetIndex(0);
//get some value from a cell
$number_value= $this->excel->getActiveSheet()->getCell('C1')->getValue();
$data['header'] = $number_value;
$this->load->view('pages/home', $data);
}
But I have also a Pages controller to control the pages of Views, and when I try to output something of PHP Excel is not possible. In my Pages.php I've wrote: $data['header'] = $number_value; and in view . But the variable "number_value" is not in Pages.php because it's only at Report.php. How can I do to output the excel data at my home.php (view) correctly?
Here is my pages.php controller
class Pages extends CI_Controller {
public function view ($page = 'home') {
if (!file_exists(APPPATH.'views/pages/'.$page.'.php')) {
show_404();
}
$data['title'] = str_replace("_", " ", $page);
$data['header'] = $number_value;
$this->load->helper('url');
$this->load->view('templates/header', $data);
$this->load->view('pages/'.$page, $data);
$this->load->view('templates/footer', $data);
}
}
I'm not very familiar with PHPExcel but here are some thoughts.
First, to use a library in a Controller it must be loaded in that controller. You cannot access one controller from another. You could duplicate the code from Report in Pages but that seems a waste. You need reuseable code.
One "reuseable" approach is to create a model that uses the excel library. This will make it easy to reuse PHPExcel code just by loading the model in any controller.
A model version including a readReport() function might look like this.
class excel_model extends CI_Model
{
protected $excel;
function __construct()
{
parent::__construct();
$this->load->library('excel');
}
function readReport()
{
$this->excel = PHPExcel_IOFactory::load(APPPATH."/third_party/teste.xlsx");
$this->excel->setActiveSheetIndex(0);
//get some value from a cell
return $this->excel->getActiveSheet()->getCell('C1')->getValue();
}
}
Pages controller should be modified as follows.
class Pages extends CI_Controller
{
public function view($page = 'home')
{
//The following check isn't needed, codeigniter will do this automatically
//if (!file_exists(APPPATH.'views/pages/'.$page.'.php')) {
//show_404();
//}
$this->load->model('excel_model');
$this->load->helper('url');
$data['title'] = str_replace("_", " ", $page);
$data['header'] = $this->excel_model->readReport();
$this->load->view('templates/header', $data);
//You don't have to keep sending $data to the views because
//any variables loaded by the first call to load->view()
//will be visible the all other views loaded in this function.
$this->load->view('pages/'.$page);
$this->load->view('templates/footer');
}
}
I have two views ie, views/pages/home.php and views/pages/search_result.php. I have a controller to load this views ie, controllers/Pages.php. And also i have one more folder inside view ie, views/templates/header.php and views/templates/footer.php
When i am pointing the browser to http://localhost/codeigniter/home everything working perfect.
But the problem is when i am pointing the browser to http://localhost/codeigniter/search_result, the view footer.php is also showing. Actually am not given anything inside search_result.php
My controller code is,
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Pages extends CI_Controller {
public function home($page = 'home')
{
//code to show home.php (http://localhost/codeigniter/home)
if (!file_exists(APPPATH.'/views/pages/'.$page.'.php'))
{
// Whoops, we don't have a page for that!
show_404();
}
else
{
$data['title'] = ucfirst($page); // Capitalize the first letter
$this->load->view('templates/header', $data);
$this->load->view('pages/'.$page, $data);
$this->load->view('templates/footer', $data);
}
}
public function search_result($page = 'search_result') {
//code to show search_result.php (http://localhost/codeigniter/search_result)
}
}
Inside search_result function i didn't given any code and while am pointing to http://localhost/codeigniter/search_result the footer from function home is showing ie, $this->load->view('templates/footer', $data);
What am doing wrong. Is there any solution to solve this issue. I am beginner in codeigniter.
Just simply try this
public function home()
{
//code to show home.php (http://localhost/codeigniter/home)
if (!file_exists(APPPATH.'/views/pages/home.php'))
{
// Whoops, we don't have a page for that!
show_404();
}
else
{
$this->load->view('templates/header', $data);
$this->load->view('pages/Home', $data); # changed
$this->load->view('templates/footer', $data);
}
}
I am still new at PHP and the MVC concept. I have been trying to duplicate the CI News Tutorial(http://codeigniter.com/user_guide/tutorial/news_section.html), while using my own database and rewriting the code.
I have been unsuccessful.
Here is my controller:
class Main extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->helper('url');
$this->load->library('tank_auth');
$this->load->model('structures_model');
}
public function structures()
{
$this->load->model('structures_model');
if (!$this->tank_auth->is_logged_in()) {
redirect('/auth/login/');
} else {
$data['structures_all'] = $this->structures_model->get_structures();
$this->load->view('templates/header', $data);
$this->load->view('templates/navmain', $data);
$this->load->view('structures', $data);
$this->load->view('templates/footer', $data);
}
}
Here is my model (structures_model)
<?php
class Structures_model extends CI_Model {
public function __construct()
{
$this->load->database();
}
public function get_structures()
{
$query = $this->db->get('structures');
return $query->result_array();
}
}
And my view:
<?php foreach ($structures_all as $structures_info): ?>
<h2>Structures</h2>
<div id="main">
<?php echo $structures_info['str_name'] ?>
</div>
<?php endforeach ?>
The error im getting is the common :
A PHP Error was encountered<
Severity: Notice
Message: Undefined variable: structures_all
Filename: main/structures.php
Line Number: 2
I am at a loss. I have looked at all the similar errors people have gotten, but can't figure out why exactly the structure_all array is not being defined. Shouldn't it get created in the controller function where I set :
$data['structures_all'] = $this->structures_model->get_structures();
What am I missing?
The best way to debug this would be to assign $data['structures_all'] a definite array value, say: $data['structures_all'] = array('foo' => 'bar');
Is the $structures_all variable available in the view now? If it is available, you know that $this->structures_model->get_structures(); is returning null.
Do you have a table in your database called structures?
Are you sure your database connection details are filled out in config/database.php?
Do you have php error reporting set to all? There might be hidden messages... call error_reporting(E_ALL); in the constructor of your controller.
Also try echoing: $this->db->last_query(); to verify your query is being constructed the same way you tried in phpmyadmin...
Hopefully this puts you on the right track.
Consider my code:
<?php
class MY_Controller extends Controller {
public function __construct()
{
parent::Controller();
}
function _displayPage($page, $data = array()) {
$this->load->view('structure/header', $data);
$this->load->view($page, $data);
$this->load->view('structure/footer', $data);
}
}
?>
page.php
<?php
class Page extends MY_Controller {
function __construct() {
parent::__construct();
}
function index() {
$data['content'] = array('title'=>'hello world');
$this->_displayPage('home', $data);
}
}
?>
Upon loading my page on my browser, I get this error:
A PHP Error was encountered
Severity: Notice
Message: Undefined property: Page::$view
Filename: libraries/MY_Controller.php
Line Number: 11
Does anyone know what I'm doing wrong?
Thanks
In your library My_Controller you should be using the parent keyword instead of $this.
your code should look like so:
class MY_Controller extends Controller
{
public function __construct()
{
parent::Controller();
}
function _displayPage($page, $data = array())
{
parent::load->view('structure/header', $data);
parent::load->view($page, $data);
parent::load->view('structure/footer', $data);
}
}
If I understand what you're trying to accomplish correctly, you're wanting to setup a template that includes your header view and footer view, but without calling header and footer views for each controller you use throughout your application. Here's what I've done to accomplish this.
First, create a new folder under your views, for this example we'll call it 'includes'. Inside the newly created includes folder, create three files, header.php, footer.php and template.php. Setup your header and footer appropriately and then edit your template.php to look as follows:
<?php echo $this->load->view('includes/univ_header'); ?>
<?php echo $this->load->view($main_content); ?>
<?php echo $this->load->view('includes/univ_footer'); ?>
Now, from your controller you can define what view you would like to set as your 'main_content'. For example, if you have home.php in your views folder and you want to wrap it with your header and footer you would do so in your controller as follows:
function index() {
$data['content'] = array('title'=>'hello world');
$data['main_content'] = 'home';
$this->load->view('includes/template', $data);
}
Hope this helps!