I'm new to Codeigniter and PHP in general, so bear with me.
I'm attempting to use the codeigniter pagination class to paginate the results returned from a query. The code below works fine with static queries that don't require any parameters passing. However, it seems to break down when attempting to pass a variable as a parameter in the URL e.g.
localhost/index.php/termsbyletter/index/a
where 'a' is the $letter variable passed to the controller/model.
PHP isn't outputting any errors and the query performs as expected, as does the record_count function within the model. The result is that all of the query results are displayed, but all on the same page, which stays the same when the pagination links are clicked.
Also, in the model, is there a more efficient way of returning the row count than running the query twice? I've read on here that this is necessary, and I haven't had any success trying to pass this value any other way.
Here is my controller:
<?php
class Termsbyletter extends CI_Controller
{
public function __construct() {
parent:: __construct();
$this->load->helper("url");
$this->load->model("terms_by_letter");
$this->load->library("pagination");
}
public function index($letter) {
$config = array();
$config["base_url"] = base_url() . 'index.php/termsbyletter/index/' . $letter;
$config["total_rows"] = $this->terms_by_letter->record_count($letter);
$config["per_page"] = 3;
$config["uri_segment"] = 5;
$this->pagination->initialize($config);
$page = ($this->uri->segment(5)) ? $this->uri->segment(5) : 0;
$data["results"] = $this->terms_by_letter->term($config["per_page"], $page, $letter);
echo $this->pagination->create_links();
$this->load->view("/templates/header");
$this->load->view("/terms/index", $data);
$this->load->view("/templates/footer");
}
}
and the model:
class Terms_by_letter extends CI_Model
{
public function __construct() {
parent::__construct();
$this->load->database();
}
public function record_count($letter) {
$query = $this->db->query("SELECT * FROM news WHERE LEFT(slug, 1) = '$letter'");
return $query->num_rows();
}
public function term($limit, $start, $letter) {
$this->db->limit($limit, $start);
$query = $this->db->query("SELECT * FROM news WHERE LEFT(slug, 1) = '$letter'");
if ($query->num_rows() > 0) {
foreach ($query->result() as $row) {
$data[] = $row;
}
return $data;
}
return false;
}
}
and I'm using something like this to output the results in the view:
<?php
foreach($results as $data) {
echo $data->slug "<br>";
}
?>
<p><?php echo $links; ?></p>
You're trying to mix active records with normal CI queries and that won't work. Change the query to:
$query = $this->db->query("SELECT * FROM news WHERE LEFT(slug, 1) = '$letter' LIMIT $start, $limit");
Either that or go the active record route entirely with:
$this->db->limit($limit, $start);
$this->db->where('LEFT(slug,1)',$letter);
$this->db->get('news');
As far as I know there is no way to return all the results you need with a single query, the controller needs total records to figure out the pagination, then it needs to select just the records for one page.
You could however just write the query once and change the parameters a bit.
public function term($limit, $start, $letter) {
if($limit > 0)
{
$this->db->limit($limit, $start);
}
$this->db->where('LEFT(slug,1)',$letter);
$this->db->get('news');
Then in your controller you'd get the count like this:
$config["total_rows"] = $this->terms_by_letter->term(0,0,$letter);
Related
I am doing ajax scrolling pagination. Controller is like below
<?php
require APPPATH . '/controllers/user/Usercontroller.php';
class PaginationController extends Usercontroller{
public function __construct(){
parent::__construct();
$this->load->model("Usermodel","",true);
}
private $perPage = 5;
public function index(){
$tutorId=$this->session->userdata('cp_userid');
$categorycourses=$this->Usermodel->getcourses($tutorId);
$count = $categorycourses->num_rows();
$data['details']=$categorycourses;
$this->load->view("user/pagination_view",$data,true);
}
}
?>
$count variable contains 5 data, I want to send 3 for first page and remaining for second page. How to do this.
Try this...
Model:
function getcourses($tutorId, $limit = null) {
$this->db->select('*');
$this->db->from('courses');
$this->db->where("tutorId", $tutorId);
//$this->db->order_by("name", "asc");
if($limit!=''){
$this->db->limit($limit);
}
$query = $this->db->get();
$courses = array();
foreach ($query->result() as $row)
array_push($courses, $row);
return $courses;
}
Controller:
public function index(){
$tutorId = $this->session->userdata('cp_userid');
$limit = 3;
$categorycourses = $this->Usermodel->getcourses($tutorId, $limit);
//$categorycourses=$this->Usermodel->getcourses($tutorId);
$count = $categorycourses->num_rows();
$data['details'] = $categorycourses;
$this->load->view("user/pagination_view", $data, true);
}
I have created one new function in a existing controller, in which I am accessing a model's function which has a query to get the list.
I have loaded the model in controller. This model function works with other function but not working for new created function.
class Cart extends CI_Controller
{
function Cart()
{
parent::__construct();
$this->mdl_common->checkUserSession();
$this->load->model('mdl_friend_web');
$this->load->model('api/mdl_friend','mdl_friend_api');
$this->load->model('mdl_cart_web');
$this->load->library('pagination');
}
//works for this function
function ajax_get_cart_list($offset = 0)
{
is_ajax();
$this->load->model('mdl_cart_web');
$limit = PER_PAGE;
$s_data = $_POST;
$carts = $this->mdl_cart_web->get_cart_list($limit,$offset,$s_data)->result_array();
$totalRows = $this->mdl_cart_web->get_total_cart_product($s_data)->num_rows();
$data = $this->mdl_common->pagination_data('cart/get_cart_list/',$totalRows,$limit,'show_data');
$data['carts'] = $carts;
$data['total_cart'] = $totalRows;
$html = $this->load->view('cart/ajax_cart_list',$data,true);
echo $html;
}
//not working for this
function calculate_distance()
{
$limit = '';
$delivery = 0;
$previousName = '';
$count = 0;
$oneShop = '0';
is_ajax();
// $this->load->model('mdl_cart_web');
$lat1 = $_POST['lat1'];
$long1 = $_POST['long1'];
// $user_id = $_POST['user_id'];
$user_id = $this->session->userdata('user_id');
$carts = $this->mdl_cart_web->get_cart_list($limit,0,'')->result_array();
$response = array();
$data['carts'] = $carts;
foreach($data['carts'] as $row) {
echo $row['store_latitude'];
}
}
model
<?php
class Mdl_cart_web extends CI_Model
{
/*=================================================================================
Get cart list
==================================================================================*/
function get_cart_list($limit,$offset,$data)
{
$this->db->select('c.*,p.*,s.name as store_name,s.latitude as store_latitude,s.longitude as store_longitude,count(r.product_id) as review , IFNULL(AVG(r.star),0) as avg_star,i.*',false);
$this->db->join('p_product as p','c.product_id = p.product_id','left');
$this->db->join('p_product_image as i','c.product_id = i.product_id','left');
$this->db->join('p_product_review as r','c.product_id = r.product_id','left');
$this->db->join('p_store as s','s.store_id = p.store_id','left');
$this->db->limit($limit,$offset);
$this->db->where('c.user_id',$this->session->userdata('user_id'));
$this->db->group_by('c.cart_id');
$this->db->from('p_cart as c');
return $this->db->get();
}
?>
I am not able to get the array data.I can see blank alert.
What is going wrong here? Please help.Thank you.
I think you are writing your query not properly try this:
$this->db->select('c.*,p.*,s.name as store_name,s.latitude as store_latitude,s.longitude as store_longitude,count(r.product_id) as review , IFNULL(AVG(r.star),0) as avg_star,i.*',false);
$this->db->from('p_cart as c');
$this->db->join('p_product as p','c.product_id = p.product_id','left');
$this->db->join('p_product_image as i','c.product_id = i.product_id','left');
$this->db->join('p_product_review as r','c.product_id = r.product_id','left');
$this->db->join('p_store as s','s.store_id = p.store_id','left');
$this->db->limit($limit, $offset);
$this->db->where('c.user_id', $this->session->userdata('user_id'));
$this->db->group_by('c.cart_id');
return $this->db->get();
As Above comment and after seeing your question that the model works fine for the one function and not for the other so I think that loading a model is what you have to look properly.
I see that in your not working function you have noticed some basic problems.
You have commented the model loading code after is_ajax(). // $this->load->model('mdl_cart_web'); so first remove that comment and try again.
Send Correct and proper data to the model. Please Check this below line of code that is executing properly or not.
In Your Not working model.
$carts = $this->mdl_cart_web->get_cart_list($limit,0,'')->result_array();
In Your Working Model:
$carts = $this->mdl_cart_web->get_cart_list($limit,$offset,$s_data)->result_array();
And One thing I want if you are using the same model in more functions in the same controller then you should use __construct()
public function __construct() {
parent::__construct ();
$this->load->model('mdl_cart_web');
}
By adding a model into the __construct() you can use it in the entire controller and all of the functions.
This is my query counting rows in tblapplication
public function countallrecord() {
$query = $this->db->get('tblapplication');
return $query->num_rows();
}
and this is the function to get all the data
public function getdata() {
$query = $this->db->get('tblapplication');
return $query->result();
}
Is there any way I can make this code on one function
I'm trying to pass it here:
public function Countandviewallrecord() {
// returns both rows and count
}
Just return it as an array. Include the results and count in their respective indices:
public function get_records()
{
$result = $this->db->get('tblapplication');
$data['results'] = $result->result();
$data['count'] = $result->num_rows;
return $data;
}
When accessing the model method in your controller, the usual:
$data = $this->model_name->get_records();
echo $data['count']; // whatever number this is
if($data['count'] > 0) {
foreach($data['results'] as $row) {
echo $row->column_name; // etc blah blah ..
}
}
this Countandviewallrecord will display data as well count total records
public function Countandviewallrecord(){
$TotalRecords= $this->countallrecord();
$totalData= $this->getdata();
}
I am getting the below error on my code,
Call to a member function num_rows() on boolean in C:\xampp\htdocs\codeigniter\application\controllers\go.php on line 15
Code:
<?php if (!defined('BASEPATH')) {
exit('No direct script access
allowed');
}
class Go extends MY_Controller
{
function __construct()
{
parent::__construct();
$this->load->helper('string');
}
public function index()
{
if (!$this->uri->segment(1)) {
redirect(base_url());
} else {
$url_code = $this->uri->segment(1);
$this->load->model('Urls_model');
$query = $this->Urls_model->fetch_url($url_code);
if ($query->num_rows() == 1) {
foreach ($query->result() as $row) {
$url_address = $row->url_address;
}
redirect(prep_url($url_address));
} else {
$page_data = array(
'success_fail' => NULL,
'encoded_url' => FALSE,
);
$this->load->view('common/header');
$this->load->view('nav/top_nav');
$this->load->view('create/create', $page_data);
$this->load->view('common/footer');
}
}
}
}
#ahmed is correct that db code belongs in the model but the problem you're having is most likely from a db error.
Besides fixing the problem, the workaround is this.
if ($query->num_rows() == 1) {
should be changed to
if ($query && $query->num_rows() == 1) {
I would put an else in there to dump the $this-db->error() to the error_log so you can see what the problem is.
You should call the 'num_rows()' inside the Model, not the Controller, for this function is used often after the get() method:
//Model function:
$query = $this->db->get();
$data = Array();
if($query->num_rows()){
//Work with data:
foreach($query->result_array() AS $row){
$data[] = $row;
}
}
return $data;
I suppose if you want to use the num_rows inside the controller, you should return the query AS a result like this:
$query = $this->db->get();
return $query;
$data = [];
$this->db->where('', 0);
$query = $this->db->get('');
if ($query->num_rows()>0)
{
foreach ($query->result_array() as $row)
{
$data[] = $row;
}
}
$query->free_result();
return $data;
First of all check that values come from database. if values come from table then put greater than 0 . if your value exist then query run forword. i thank this is help for you
This is caused by buggy Active Records in CI that adds an extra WHERE clause causing ambiguous column names and similar.
Try to get the actual query with $this->db->last_query(); and it will be instantly clear why $query is not an object.
I have a situation, I have written a base model in codeigniter, all models extend from it, the base model has a function
public function load_all_by_keys($array, $limit = 0, $offset = 0) {
if ($limit) {
$query = $this->database->get_where($this::DB_TABLE, $array, $limit, $offset);
} else {
$query = $this->database->get_where($this::DB_TABLE, $array);
}
$ret_val = array();
$class = get_class($this);
foreach ($query->result() as $row) {
$model = new $class;
$model->populate($row);
$ret_val[$row->{$this::DB_TABLE_PK}] = $model;
}
return $ret_val;
}
in this function I am able to get lets say for instance, schools which are of category Abet
$abet = new School_Model();
// this query will get all schools with by column category whose value is Abet, thats fine
$abetSchools = $abet-?load_all_by_keys(array('category'=>'Abet'));
$primary = new School_Model();
// This second query fails with the error Fatal error: Call to a member function result() on a non-object
$primarySchools = $primary-?load_all_by_keys(array('category'=>'Primary'))
Can someone help
$this->db->flush_cache()
This function deletes all items from the Active Record cache (Reference http://ellislab.com/codeigniter/user-guide/database/active_record.html#caching)