I want to cache a query in CodeIgniter. What I did for my test is make a controller, that I named show.php:
class Show extends CI_Controller{
public function __construct()
{
parent::__construct();
$this->load->model('rejaal_show');
}
public function _remap($method = '',$param = array())
{
$method = intval($method);
$this->output->cache(5);
var_dump ($this->rejaal_show->temp($method));
}
}
And a model that I named rejaal_show.php:
public function temp($id)
{
$this->db->cache_on();
$this->db->where('id',$id);
$query = $this->db->get('system_store_table');
return $query->result();
}
When I call http://localhost/rejaal/show/1 for the first time, it will show a result, but when I call it for the second time, it does not show anything.
I should delete the query cache file to show it again? How should I solve this problem?
With special thanks for your attention.
Can you confirm that you have set $db['default']['cachedir'] to the path of a writable folder in application/config/database.php and that when the query is first run it creates a cache file in there?
The only other reason I can think of for it failing is by your use of the _remap override. I have not used db caching using _remap, but know that CodeIgniter creates a folder called controller+action in your cache folder, and might not be handled very well if using remap? Someone correct me if I am wrong about this.
In the CodeIgniter User Guide page for Web Page Caching, it says:
Because of the way CodeIgniter stores content for output, caching will only work if you are generating display for your controller with a view.
Do your var_dump inside a view.
Related
I'm posting this after my hair has been ripped out, ran out of rum, and tried everything I can find on google. I've been developing a site using codeigniter which makes use of templates. I've built the backend first and all is working properly there. So now i've started on getting the front end working which is where I'm hitting the issue.
I've created a controller called pages.php which is going to parse the uri string of the current page, use my library to get the page data from the database, then display it. My pages are all created through an editor on the back end and stored in the database.
So here's the pages controller
class Pages extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->library("pages");
}
public function display_page()
{
$page_slug = $this->uri->segment(1);
$data["joes"] = "Here's joes first variable";
$this->pages->get_page($page_slug);
}
}
and here's the error message i get when i hit my url like this demo.mydomain.com/joes-test
and here is how my routes are set up. $route['(:any)'] = 'pages/display_page';
My Pages.php library works perfect on the back end but it's a large file. I've only posted the get_page function below. If you need to see everything let me know. But i dont believe the issue has anything to do with the library itself.
public function get_page($slug){
$objPages = new pages();
$objPages->get_object('slug="'.$slug.'"');
return $objPages;
}
[EDIT] If i place the following inside my homepage controller it works. But the calling function needs to be inside the library.
$this->load->library('pages');
$the_page = $this->pages->get_page("joes-test");
I want to call $this->get_object("joes-test") but this doesn't work. get_object() is an inherited function inside the library.
Now oddly enough. The code i put above will NOT work if i do the exact same thing inside the pages controller
any help leading to a solution would be awesome. I'm under a time crunch and pay to get some assistance. Thanks in advance.
No you can't use the same name with controller and library. please choose another name. for example Mypages for you controller name.
change your routes
$route['(:any)'] = 'mypages/display_page';
then call your controller.
http://demo.mydomain.com/joes-test
I think there nothing wrong with library uri, because as codeigniter official website say: This class is initialized automatically by the system so there is no need to do it manually.
I don't know about lib pages, but how about use
$this->load->view(<file-html>);
and if you want to passing data in variable, you can add variable like this
$this->load->view(<file-html>, $data);
Hope this help, Cheers
I need a help to figure out one issue with the codeigniter caching.
I am running two functions to store a result in cache. This function is in my model :
public function cacheAllCurrencies()
{
$this->db->cache_on();
$this->db->select("name,icon,currency_code");
$this->db->from("currency");
$this->db->where("status='Active'");
$cache_currency_result = $this->db->get()->result();
$this->db->cache_off();
return $cache_currency_result;
}
public function cacheAllCategory()
{
$this->db->cache_on();
$this->db->select("name,url");
$this->db->from("category");
$this->db->where("parent_category='0'");
$this->db->where("status='Active'");
$this->db->order_by('name','ASC');
$cache_category_result = $this->db->get()->result();
$this->db->cache_off();
return $cache_category_result;
}
My these two functions are called in header view like below :
$CI =& get_instance();
$CI->load->model(PUBLIC_DIR.'/commonPage','common');
$currencies = $CI->common->cacheAllCurrencies();
$categories = $CI->common->cacheAllCategory();
Now, when all the page loads, it creates a cache file according to the page opened like home, blog, blog+blogname etc.
Both query generates two cache file in cache folder
1580e4c2413cb09f6ed3bc7fae8cee45 - first function cache result
d7e2452b0424f859e1a5984bd26cbd6c - second function cache result
Now, I have two questions :
I need to delete 1580e4c2413cb09f6ed3bc7fae8cee45 cache file when I update currency table same for the category.
How this file name generated ? I mean how codeigniter generates cache file name. In my cache 1580e4c2413cb09f6ed3bc7fae8cee45 for currency and d7e2452b0424f859e1a5984bd26cbd6c for category.
I hope this explanation makes sense and I hope most of the codeigniter developer having this problem which need to be sort it out.
Thanks,
Ali
In Codeigniter, you can clear the cache of DB using the table name
like
$this->db->cache_delete('currency');
$this->db->cache_delete('category');
OR two table cache at the same time
$this->db->cache_delete('currency','category');
EDIT :
CodeIgniter save filename by md5() encryption of SQL query
public function cacheAllCurrencies(){
$this->db->cache_on();
$this->db->select("name,icon,currency_code");
$this->db->from("currency");
$this->db->where("status='Active'");
//here you get filename
$file_name=md5($this->db->get_compiled_select());
$cache_currency_result = $this->db->get()->result();
$this->db->cache_off();
return $cache_currency_result;
}
I made a view composer in Laravel 5. When i use a wildcard *, to add something to all my views, it get's called at least twice. It runs when my master template is loaded, and again when my content page is included. This will give problems in the future, because it executes the query it does multiple times. I was able to fix the multiple querying by storing it in a static variable :
class StoreComposer {
static $composed;
public function __construct(StoreRepository $repository)
{
$this->store = $repository;
}
public function compose(View $view)
{
if(static::$composed)
{
return $view->with('store', static::$composed);
}
static::$composed = $this->store->pushCriteria( new WithCategories() )
->pushCriteria( new WithSettings() )
->applyCriteria()
->all();
$view->with('store', static::$composed);
}
}
My question is, is there a way to make sure it only runs once, no matter how many views i load, or is there another solution to this? The way i fixed it now doesn't feel right to me. Thanks!
Unfortunately no, there is no way to make it run once, due to the way View Composers are implemented. The Illuminate\View\View::renderContents() method is responsible for calling the composer bound to a view, and since any form of view rendering (Blade template inheritance or simple #include statements) executes that method, it means that when any view is rendered any composer bound to it gets triggered.
Since in your case you use a * wildcard to bind all views, if your page renders ten views, the composer will get executed ten times. However your approach looks like a good solution to solve this shortcoming.
You can use config here to resolve multiple times query run issue for example show below code.
public function compose(View $view)
{
if(!Config::has('composeVars'))
{
Config::set('composeVars') = [
'data' => User::all();
];
}
$view->with('*', Config::get('composeVars'));
}
Try this singleton solution or use cache https://laracasts.com/discuss/channels/laravel/executing-a-view-composer-only-once
On Laravel 5.6.38 works fine
I've looked around in the documentation and a few other places and I am not sure how to achieve the results I want. I have a domain name set up that will only server public profile pages to visitor. When someone comes straight to the site I want it to display a welcome screen telling more about what the website is about. (example.com) When someone visits example.com/my-public-page I want it to run a default controller that grabs the 'my-public-page from the url, searches the database for a user with that info in a column and displays their info.
I would image that I just set the default_controller to my controller and then check for a second string in the url. If its present search for that in the database. After looking around I am not sure how to make this work and not sure what to search for to get the results I need.
Thanks for your help,
After defining an encryption key for sessions in config.php you can use something like this:
class Wellcome extends CI_Controller {
public function __construct() {
parent::__construct();
$this -> load -> library('session');
if(!$this->session->userdata('visit_time')) {
$this->session->set_userdata('visit_time', time());
redirect('first_visit');
}
}
}
while working yesterday with codeIgniter I found some strange(I don't know what to call),maybe I don't know whether it is normal or not as am a rookie using this framework.Below is my controller class.
class Posts extends CI_Controller
{
public function __construct() {
parent::__construct();
$this->load->model( 'post' );
}
public function index() {
// echo "<pre>";
// print_r($data['posts']);
// echo "</pre>";
$data['posts']=$this->post->get_posts();
$this->load->view( 'post_index', $data );
}
public function post( $postID ) {
$data['post']=$this->post->get_post_by_ID( $postID );
$this->load->view( 'post', $data, FALSE );
}
I found that strange in function "post" the reason is simple if I change the function name then I will get the error-page not found.
Why is that?? Is it necessary to have function name and view name to be same.As I told am a beginner to this framework.So please co-operate and provide your precious feedback.
Function name and view name do not need to be the same. Your view can be anything you want it to be so long as you call the filename (and sometimes path) correctly :)
The biggest problem I see here is you are trying to access some object called posts, which I do not see defined. I have a good hunch you're looking for the "input" object provided by code igniter.
That being said, replace:
$this->post->get_posts();
With:
$this->input->post(NULL,true);//return all post objects with cross site scripting scrub
And replace:
$this->post->get_post_by_ID($postID);
With:
$this->post->post('postID',true);//same as above, except again, with XSS scrub enabled.
If this is not your answer and you need me to re-evaluate, please let me know in a comment and I'll redo the answer.
With regards to your page not found issue, it's because Codeigniter automatically assumes the paths depending on what you name your functions. It uses the following convention by default (routes.php allows you to override this in config/routes.php)
site.com/index.php/controller_name/method_name/param_1/param_2/param_n
Or if you have mod_rewrite taking out the front controller
site.com/controller_name/method_name/param_1/param_2/param_n
Since the view is loaded from the controller function itself, if you change the name of that function, then the URL will no longer be able to "find" it, hence the error.