Smarty Caching vs roll your own? - php

As far as I understand it, when you turn on caching in smarty, smarty caches compiled templates. These compiled templates can then used to speed up rendering of the page. Wouldn't it be a good idea to run you own level of caching on top of your smarty application that goes like this.
if(a cache for this page exists){
-Don't run my application, don't include my files don't instantiate my classes.
-Send the cached version of this page to the user
-end the script here
}else{//if the cache for this page does not exist or is not current
- run my application as usual
-save all the output to a file for next time
}
The whenever somthing happens on my site that would update the content of the this page, eg the admin makes changes to the content of the site delete the cache file. I feel like I must be missing something here. This method would allow me to store an all html version of every page and send that when it is valid. It seems like this would drastically improve the speed of my site.
Edit: Ok so I have discovered that smarty does infact store a html version of my site. How do I prevent my application from running if the rest of my application from running if the cache is current. Do I just include and instantiate smarty first and do something like
if($smarty->usingcache())[
exit;
}

If your site were static, this would work. But in that case, you wouldn't need Smarty...
Suppose you update a record in your database. Then all pages in your site which contain output directly or indirectly affected by the update would have to be invalidated. How would you know which pages to invalidate?

How can you know what the page will look like until you do some request specific processing. Until you've checked your client's authentication status, performed some database queries ( or fetched cached results) to fetch recent information, you can't know if the most recently rendered page is the same as what would be rendered this time. Smarty solves this with this strategy:
Your app does all of it's domain/business logic in response to the request.
Your app populates the smarty template instance with template variables
Smarty generates a hash of the template and the template variables
If the hash is not in the cache, Smarty renders the template and caches it
If the hash is in the cache, Smarty returns the cached template instead of rendering
If the cache is full, smarty evicts an old, cached page to make room.
By default, Smarty uses the filesystem for the Cache, but it the caching strategy is compatible with any key-value store. In fact, plugins exist for other stores, such as this one for memcached.

Related

Codeigniter page cache not considering inputs?

How can I get CodeIgniter page cache to take inputs into account? For example, say I have a pagination system. With cache enabled, if I go to page 1, then page 2 (same controller)... CI cache will return page 1's content.
function my_controller() {
$this->output->cache(1);
$page = $this->input->post("page");
$data = getData($page);
$this->load->view('my_view', $data);
}
In the above example, you cannot pan through pages correctly. It will keep loading the cached page even if the posted input changes.
How can I get the cache system to take $_POST data into account and treat those as different requests from a cache point of view?
Caching dynamic content where the view has no noticeable change to the caching class can get messy...
The simplest solution is don't cache dynamic pages, its not really what caching is for anyway, caching is meant for (at least, mostly) static data.
Another way you can do it (depending on result sets) is to use javascript and paginate client side, and use ajax calls to fetch the data from the server, the client would never actually leave the single view and only the initial view would be cached.
How often does the content change? are we talking like a list of orders that changes minute by minute, or a list of products that changes maybe monthly?
If loaded by ajax then just make sure what you are calling is not exposed to your cache (unless the content rarely changes)... As it would be called from a different method this is not difficult to ensure, and on page load you would have it call the first xx number of results fresh every time, but using the benefits of caching for the rest of the view.

Skip/ bypass the SERVER cache file/caching if there's a query string in the url?

I have a home page as index.php and it gives a list of 10 items/ products.
Now, I am using the same page as landing page for inward traffic from facebook.
The url looks like index.php?productID=Q231 This page displays the product carrying the specified ID only.
I am aware of PHP output caching but I am new. I have learned that if I cache index.php, it will serve the same cached file to all the inward traffic from facebook.
Is my understanding correct? I have searched a lot about this but i am not clear as to how would one go about caching with this instance.
Is there a a way to skip or bypass the server cache file/caching if there's a query string in the url?
I would greatly appreciate if anyone could give me some pointers.
It really depends on your caching model and how you handle this in your code.
If you are creating the whole thing using output buffering you may want to use a method such as:
Generate Cache key based on requested script and/or request parameters i.e. using productId in your case
Check to see if you have saved the output for a given key to some persistent store
If yes, output
If no, then use an output buffer, generate the contents, save to a persistent store and save under the generated cache index, and output
Googling brings up this rudimentary example:
http://www.devshed.com/c/a/PHP/Output-Caching-with-PHP/
if i'm not mistaken caching is not based on referrer. Internal php caching is only to optimize code, it will not cache, as ie. 'external' caching systems, like inbuild caching in smarty for example, output. I think you'd only need to 'disable' caching for browsers, which will mean, send the proper headers with header(...)
You are using output caching. Then you should clear cache when your facebook or twitter links called. IN codeigniter(Framework of PHP), I have done this by clearing cache.
In core PHP, I don't know how to clear cache. But there must be some methods to clear cache. So try for that.
Here some links may be useful to you.
How to clear browser cache with php?
http://php.net/manual/en/function.clearstatcache.php
http://www.dreamincode.net/forums/topic/6519-clear-cache/

Aggressive caching of generated contents while maintaining auth info

I'm using a Symfony 2 to generate my pages from data in a MySQL database. For most content, users have to be authenticated but the content itself does not change often and does not need to be customized for the users. So what's a good caching strategy for avoiding database calls while still maintaining the auth check?
Simply put, use Memcache to cache the SQL result-set for extended period of time.
Maybe this be too huge change, but the following scheme may be useful in the case:
Create several sets of pages, one for not-yet-authed users (let's put in the site root), and others for authenticated users that should see the same content (say, it two or more should see the same content when they are authenticated, then we'll create only one set for all of them), and put it into directory under root. Then form simple .htaccess/.htpasswd files for each of such 'for-authed-only' directory and then it'll be webserver's problem not your script.
Hope you got the idea. It is fuzzy to say, but will be easy to implement.
Example: say you care to allow only authenticated users to see page '/topsecret.html' on the site. Create dir (/authed), establish HTTP-auth on it, and put your topsecret.html into the dir (so it'll be '/authed/topsecret.html'). Now edit '/topsecret.html' and simple replace it's main content with 'sorry, please authenticate yourself' link that'll point to '/authed/topsecret.html'.
If you use Symfony2, you are using Doctrine2
if you use Doctrine2, caching should be enabled by default.
Choose your cache driver for your purposes and there should be no problem.
You might also be specifically interested in query result caching.
Do not use Doctrine without a metadata and query cache! Doctrine is
highly optimized for working with caches. The main parts in Doctrine
that are optimized for caching are the metadata mapping information
with the metadata cache and the DQL to SQL conversions with the query
cache. These 2 caches require only an absolute minimum of memory yet
they heavily improve the runtime performance of Doctrine. The
recommended cache driver to use with Doctrine is APC. APC provides you
with an opcode-cache (which is highly recommended anyway) and a very
fast in-memory cache storage that you can use for the metadata and
query caches
I solved this by using Zend_Cache inside the cacheable actions to store the rendered template result. I then create a new Response object from the cached content. If the cache is empty, I generate the content.
I thought of creating a plugin that checks for an annotation and stores the Response output automatically but it turned out that I only have 3-4 display actions that are cacheable and have very complex cache ID creation rules, so I put the caching logic directly into the controller code.
It appears that you have a lot of options for caching with symfony http://www.symfony-project.org/book/1_2/12-Caching (not for 2 but my guess is not a lot has changed).
You could put your heavy sql statements in its own script and turn caching on for that script
list:
enabled: on
with_layout: false # Default value
lifetime: 86400 # Default value
Further if you are sure that the generated tag won't change for a while you could use symfony to tell the user's browser not even to bother your server for the content which will cause the page to load nearly instananeously for the user.
$this->getResponse()->addCacheControlHttpHeader('max_age=1200'); // in seconds - less than 1 year seconds
Just make sure your max age is small enough that when something changes (say a code update) that the user doesn't get stuck with old page since there is no way to force them to request that page again short of changing the url.

Render cache if cache is exists, if not render nothing with Symfony

What I'm trying to do is render either a partial or a fragment in Symfony from the cache (the easy part) but if the cache does not exist, then I want Symfony to (instead of recreating the cache) render nothing.
My website pulls data from multiple other websites, which can insanely slow down page rendering speed, so instead of loading the info from other websites on the initial page load, I plan on doing it once the initial page is finished loading and a user clicks the appropriate button, then caching the data for later. However, if the data is cached (from a previous request) then I would rather dump the cached data right into the initial page load.
I tried to clarify it as much as possible, so hopefully it makes sense.
i think you could handle this with a filter and the getViewCacheManager()

How does CodeIgniter output caching work?

I read this link :-
http://codeigniter.com/user_guide/general/caching.html
It is written that :-
When a page is loaded for the first time, the cache file will be written to your system/cache folder
and that we can cache a view by $this->output->cache(60);. But how does it actually work? What if regularly my users keep updating and deleting records as a result of which view changes very often. Will it show the modified data? or will the cache bring back the old stale data? (before inserts and updates)? If it automatically manages and brings fresh data from the database, then what is purpose of specifying the minutes in cache function?
Thanks in advance :)
The way codeigniter's caching works generally is this:
A page request is made. Codeigniter (before very much of the framework has even been loaded) does a hash of the current url and if it finds that filename in the cache directory, it serves that.
The only way you can get fresh data is to manually delete the files. When codeigniter doesn't find the file from the hash it generated, it dynamically creates the page.
Codeigniter's implementation is called "full page" caching, and as so, is limited in it's usefullness. There's a partial caching library I've looked into from Phil Sturgeon here: http://philsturgeon.co.uk/code/codeigniter-cache
Honestly, for most projects, full page caching really isn't all that useful. In fact, the projects that I need full page caching I don't even leave that up to codeigniter (I leave it to the webserver: it's way faster).
I'd guess what you're looking for is a partial caching method; most people would prefer this. Look into APC if you're using a single server or Memcached if you have multiple servers.
Good Luck.
But how does it actually work?
If a cached version exists that is younger than the cache time, that cached version will be outputted.
Will it show the modified data?
Eventually yes, but with a lag of $cache_time
What if regularly my users keep updating and deleting records as a result of which view changes very often.
Reduce the cache time or don't use caching at all

Categories