How to load new images, when changed in a web application - php

How to push new images in a web application, so that the cached is not taken?
When I am having a new JS or CSS file, it's easy.
Because they are in smarty templates, and I am having a version number in the URL (like a.js?v=9).
Now, the problem with images are: -
They are referred from the CSS files, and I can not have a version variable there.
So, how do you do it?

In the middle between cleanest and easiest way, I would :
In the CSS, point to images with URLs containing a distinct marker ; like "image.png?VERSION_NUMBER" (literaly)
this will allow the CSS file to be used while developping
To avoid any problem with cache, I would configure Apache (on the development machine) to indicate files should not be cached by the browser
I would use some kind of "build process", that would replace this VERSION_NUMBER marker by the real version number in every CSS file (and possibly, JS, PHP, HTML, ... )
This would create modified files, containing the right version number
Those files would be the ones deployed to the webserver
Ideally, the VERSION_NUMBER could be the SVN revision of each file ; this way, only files really modified would have to be modified ; but also harder : for each file (each URL in the CSS file !), you have to determine it's revision number before replacing the marker !
If some browser don't cache images/js/css because of the query string, the marker could be included in the files' names.
And now that you have a "build process", you can also use it to make some other manipulations, like minifying JS and CSS files, for instance
As a side note : yes, creating and testing the build process / script takes some time ; it might be easier to server CSS files through PHP, using a variable in those to indicate the version number... But, for performances, serving CSS files (at least one per PHP page ; probably more !) wouldn't be that wise ; so, probably better to take a bit more time to write the build process...

You could manually change the CSS file at the same time that you change the image file, put a "?v=1" onto the end of the image url.
You could also configure your server to send CSS files through the PHP processor, so you could stick some PHP code in there to set the "?v=8" query string on the image url.

As part of my build process, I append a querystring to javascript includes and image URLs that has the file's LastModified date/time as a long. This allows caching to work when it should, and automates something that is easy for the developer to forget.

Related

Overwriting files properly

I am trying to manage caching on heavily used webpage written in PHP. I have marked some cacheable sections of PHP code, which I want to execute only pre-cache when administrator make changes in CMS. For this, I use this method:
I have file (for example "index-source.php") with some marked ares of PHP code, which are interpretable alone. When admin change some settings, these marked parts are executed and replaced with result (for example MySQL queries which reads menu items from DB are replaced with generated HTML menu). Resulted file is saved as new "index.php", which still have some PHP code, which can't be optimized by caching.
Now to my problem
If we assume, that this server is heavilly load, which means there is for example 100 requests per second, which in PHP requires file index.php. If I will use file_put_contents() to overwrite this index.php with new pre-cached version, is there any risk, that some requests will be interrupted, because of locked/not fully overwritten file? Basically I want to somehow update my PHP file and assure that PHP will include complete old or complete new version of that file or wait few milliseconds until file is overwritten. I dont't want PHP to fail require or load partially overwritten file.
Is that possible? Thanks
file_put_contents is not what you want.
Have a look at this project, and dive into the source to get a feel for what challenges you may have to face as well as the solution chosen.
https://github.com/PHPSocialNetwork/phpfastcache

Extract all CSS rules set that have a certain rule

I was asked to change the font used in my client's website. they are using a commercial template.
I searched in the stylesheet files and saw that there are almost 400 occurrences spread in 12 different files for "font-family", I need to override them all somehow.
I don't want to use the universal rule (*) since it feels like it can cause unexpected results (like preventing me to use a second font-family)
Any Ideas?
I thought maybe I can use some tool/software to extract the entire rule in each of files into a separate file(s) and than I could easily copy them and search-replace the font family, is there such a tool/software?
I could also use PHP to look in those files and search/replace on run time but it seems like bad practice to run this on every page load.
Please advise, what would you do?
** MORE INFO: **
I don't want to edit the original files or copy them entirely. I want to extract just the rule name and the font-family attribute and value.
Example:
.some_rule {color: red;font-size: 16px;**font-family: 'whatever';**float: right;}
To become / To extract:
.some_rule {**font-family: 'whatever';**}
Then I can copy only this part to my override.css file (for example).
Thanks!
** UPDATE **
I'm sure there is a nicer way to do it, but for my needs, just to get things done in a few lines of code, this is what I did:
copied the files to temp directory
formatted them so EVERYTHING will be in a new line (declaration, attr + value, closing curly brace);
run the php code I wrote - http://codepad.org/D2YOKYJ5
This snippet creates a new file (or write to an existing one) with only what I needed.
Sounds like a replace action that a simple editor could do in a matter of minutes.
But you might consider migrating to SCSS or another CSS precompiler.
The advantage of SCSS (over SASS, for instance), is that it's completely CSS compatible, so you can just rename all CSS files to SCSS, configure an SCSS compiler, and you're up and running.
Once you've got that, you can start replacing the font family with variables or mixins, and gradually you can add more and more structure to the CSS files by refactoring certain parts of it.
If you don't want to modify the CSS at all (since it is a commercial template, and you may want to be able to download updates), you can collect all selectors for the font and make a new CSS file with them, overriding just the fonts for those specific selectors.

SASS and/or LESS - can I create dynamic CSS files on the fly?

I'm using CakePHP to build my site (if that matters). I have a TON of elements/modules each having their own file and fairly complicated CSS (in some cases).
Currently the CSS is in a massive single CSS file, but for sanity sake (and the below mentioned details), I would like to be able to keep the CSS in it's own respective file - ie css/modules/rotator.css. But with normal CSS, that would call a TON of CSS files.
So, I started looking into SASS or LESS per recommendation. But - it seems these are supposed to be compiled then uploaded. But in my case, each page is editable via the CMS, so a page might have 10 modules one minute, then after a CMS change it could have 20 or 5...etc. And I don't want to have to compile the CSS for every module if it's not going to use it.
Is there a way I can have a ton of CSS files that all compile on the fly?
Side note: I'd also like to allow the user to edit their own CSS for a page and/or module, which would then load after the default CSSs. Is this possible with SASS and/or LESS?
I don't need a complete walkthrough (though that would be awesome), but so far my searches have returned either things that are over my head related to Ruby on Rails (never used) or generic tutorials on each respective CSS language.
Any other recommendations welcome. I'm a complete SASS/LESS noob.
Clarified question:
How do I dynamically (server-side) combine multiple CSS files using LESS? (even a link to a resource that would get me on the right track is plenty!)
If you want to reduce the number of CSS files & you have one huge css file that has all the component css, just link to it on all pages & make sure you set cache headers properly.
They will load the file once and use it everywhere. The one pitfall is initial pageload time; if that's not an issue go with this solution. If it is an issue consider breaking down your compiled CSS files to a few main chunks (default.css, authoring.css, components.css eg.).
Don't bother trying to make a custom css for each collection of components, you will actually be shooting yourself in the foot by forcing users to re-download the same CSS reorganized in different ways.
Check out lessphp (http://leafo.net/lessphp/). It's a php implementation of less and can recompile changed files by comparing the timestamp.
Assuming that 'on the fly' means 'on pageload', that would likely be even slower than sending multiple files. What I would recommend is recompiling the stylesheets whenever a module is saved.
The issue of requiring only necessary modules should be solved by means of CMS. It has nothing to do with SASS or LESS.
If your CMS is aware of which modules current page has, do not run a SASS/LESS compilation (it will be painfully slow unless you implement caching which is not a trivial task). Instead, adjust your CMS's logic so that it includes each module's CSS file.
Advanced CMSs like Drupal not only automatically fetch only necessary CSS files, but also assemble them into a single file and compress it.
And if your CSS is not aware of which modules current page has (e. g. "modules" are simply HTML code that is saved into post body), then you can't really do anything.
UPD: As sequoia mcdowell says in his answer, making users download one large CSS file once is better than making them download a number of lesser CSS files that contain duplicate code. The cumulative size of all those smaller CSS files will turn out to be larger than the size of a full CSS file.

Why querystrings after images & css files?

I have seen on various sites a querystring followed by a numbers for images and css files. When I look at the source code (via Chrome Developer), the cached css files and images do not have the number in the query string in their names. I have also seen on sites where the number changes in the querystrings when I refresh the page.
As example:
myimage.jpg?num=12345
myStyles.css?num=82943
After refresh:
myimage.jpg?num=67948
myStyles.css?num=62972
Can anyone explain to me what could possibly be the purpose of these querystrings short of tracking?
Often times developers use those query strings with random numbers (or version numbers) to force the browser to request a fresh copy and avoid caching of those files since the request is different each time.
So if you have a file /image.png but it is a generated image, like perhaps a captcha or something, you could follow it with a random number querystring /image.png?399532 which the browser would then not pull image.png from its cache, but instead will download a fresh copy from the server.
Prevent caching (the query string can provide a unique URL each time the file is updated causing the browser to download a new copy and not load a stale one from its cache)
Versioning (similar to #1 but with a more specific purpose)
The query string is for version controling it force to the navigator to reload the css and the image instead of use the cache

PHP many included files

Today I read some articles about compressing multiple JS and CSS files to one in order to lower the bandwith and HTTP requests. Is there analogical situation with the php files? Is it better to create master pages that include few PHP files(header.php,footer.php and etc)in order to have a well formatted and readable code than having just a large index.php?
PHP is run on the server, and as such, only the resulting HTML is sent over to the client. Keep your files separated for clarity, it doesn't make a difference in the HTTP requests or bandwidth.
Like Xeon06 mentioned, PHP is a server-side script, and doesn't affect a bandwidth, which is size the of the content transferred through HTTP. Size of the bandwidth based on HTML, CSS, JS, Graphics, Flash and anything client-side files. Because browsers cache these kind of files, it reduces the bandwidth, because browser will get the file content from cache and not download from server again.
If I were in your shoes, I would still use includes for headers, footers or whatever is common in most pages. It just makes it easier to maintain a content and code. For example, if you have a feedback form on all pages and you want to edit a field name, link or something else, it's easier to edit one file instead of "Find and Replace" through all files you have, which doesn't work well anyways.

Categories