Manage Two Different Cache file in single cache folder in codeigniter - php

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;
}

Related

Properly cache a type-hinted model in Laravel

I'm using Redis to cache different parts of my app. My goal is to not make a database query when the user is not logged in, as the app's content don't get updated regularly.
I cache the archive queries in my controller, however when I type hint a model in the controller, the model is retrieved from the database and then passed to the controller:
// My route
Route::get('page/{page:id}', [ PageController::class, 'show' ] );
// My controller
public function show ( Page $page ) {
// Here, the $page will be the actual page model.
// It's already been queried from the database.
}
What I'm trying to do is to try and resolve the page from the cache first, and then if the cache does not contain this item, query the database. If I drop the Page type-hint, I get the desired result ( only the id is passed to controller ) but then I will lose the benefit of IoC, automatic ModelNotFoundException, and more.
I've come across ideas such as binding the page model to a callback and then parsing the request(), but seems like a bad idea.
Is there any way to properly achieve this? I noticed that Laravel eloquent does not have a fetching event, which would be perfect for this purpose.
You can override the default model binding logic:
Models\Page.php
public function resolveRouteBinding($value, $field = null)
{
return \Cache::get(...) ?? $this->findOrFail($value);
}
Read more here https://laravel.com/docs/8.x/routing#customizing-the-resolution-logic
In order to check for existence of the data in Redis, you shouldn't type-hint the model into the controller's action. Do it like this:
public function show($pageId) {
if(/* check if cached */) {
// Read page from cache
} else {
Page::where('id', $pageId)->first();
}
}

How to return once from database and store in memory in Laravel

What I want to do:
Return a bunch of rows from database, convert in a array stored in memory and make this array visible from the whole project in such a way that other controllers for example can read it. My function is simple as that:
class BoardController extends Controller
{
/*
* returns something like
* ['name' => 'description',
...
]
*
* */
public static function getAll()
{
$boards = Board::orderBy('ordem')->get();
$retorno = array();
foreach($boards as $b)
{
$retorno[$b->sigla] = $b->nome;
}
return $retorno;
}
}
If I just keep calling BoardController::getAll() it will again read from database again. I also tried making this call inside a config file into a variable and returning it there but laravel gave me a 500 error. So, what is the best practice/way to do it?
If you don't want to call the database everytime then the best approach that can be followed here is to use caching and cache the results.
The Approach is simple, You make a Database call once and cache the reaults and the next time you hit the same function you check the cache first whether its empty or not. If its not empty, then return the cached results.
Remember, the cache has a time limit otherwise if you change/update anything in the database then you'll have to clear the cache that is already stored.
Laravel has some features for caching the results. You can see it Here.
Also You can also view this link for more effective implementation of cache in Laravel.
Hope this helps.

Codeigniter: DB Cache check if record loaded from Database OR from Cache

I'm implementing a DB cache in Codeigniter and want to check if the record or the cache file EXISTS against the query.
As far as I read the Codeigniter Documentation probably, there is no way to check it. So, can anyone give me a hint if its possible?
Here is the flowchart that I would like to achieve
if (!$this->db->query_exists("QUERY HERE"))
// DO SOMETHING. Query Doesn't exists in CACHE
// Run the query in any case
$this->db->query("QUERY HERE");
Thank you!
It is unclear why you need/want to do this. Assuming query caching is enabled, the Codeigniter DB driver already does this checking and will use a cached query if it exists or will perform the query and cache it if not. The main thing you have to implement is clearing the appropriate cache when you perform record inserts, updates, or deletions that invalidate the cached results.
That said, the easiest way to determine if a cache exists is the CI_DB_Cache::read($sql) method. That method returns FALSE if a matching cache file is not found.
The DB driver has a public property - $CACHE. (Yes, it's an all uppercase variable name.) $CACHE is an instance of the CI_DB_Cache class.
This property will only be defined after a read type query has been performed. That could be a "catch 22" - you can't check for a cache file until a read query is performed, but you want to check before performing one.
Take a look at protected function _cache_init() in /system/database/DB_driver.php to see how the CI_DB_Cache class is instantiated. You might need to implement the same sort of thing in your code.
You might also find it useful to see how $this->CACHE is used in public function query($sql, $binds = FALSE, $return_object = NULL) in /system/database/DB_driver.php.
You might be able to determine if the query in question exists by using the approach that follows. I say might because I have not tested this.
$sql = "SELECT * from some_table";
//check that CACHE is defined
if(isset($this->db->CACHE))
{
$query = $this->db->CACHE->read($sql);
if($query === FALSE)
{
// DO SOMETHING. Query Doesn't exists in CACHE
}
}
$query will be a query result object if the cache is found.
However, you have to delete the cache before you can accomplish
// Run the query in any case
$this->db->query("QUERY HERE");
Without the delete you're going to end up with the same query result object you have already retrieved.
Keep in mind that the Caching class is completely dependent on the URI being requested by the browser. Caching uses the first two URI segments (controller class name and function name) to determine the folder that holds the cache file.

CodeIgniter cache clearing

I ran into a weird problem with Codeigniter Database Cache. I'm using it to cache one query result. For this I am enabling it at the begining of the function and disabling right after:
function checkAfter($lastCheck)
{
$this->db->cache_on();
$this->db->where('time >' , date('Y-m-d H:i:s', $lastCheck));
$q = $this->db->get('actions');
$r = $q->result();
$this->db->cache_off();
return (!empty($r)) ? $r : false;
}
I need to delete the cache on the certain event when something is added to database.
It is working fine with $this->db->cache_delete_all(); but when I'm trying to remove one specific method cache like it is explained in user guide it doesn't do anything.
What might be the problem here?
Both methods are called in the same Model. I also tried to enable cache before delete but still nothing.
EDIT
Lets say i have method checkEvents in my main controller which calls the checkAfter method of the model which then works with cache. CI cache engine creates a folder called main+checkEvents under cached forlder where chached data is stored.
so i am trying to remove it with
$this->db->cache_delete('main', 'checkEvents');
call in logEvent method (which saves the new event) of that model.

Query caching in CodeIgniter

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.

Categories