Combining CSS in a single request - php

Does anyone know how to achieve something like TypeKit when combining multiple CSS request? Maybe I'am not aware of that but when you list some fonts the site would generate (maybe dynamic) CSS like 567,568,569.css lo load the font-file. I thought of it as dynamic as it would change if you use other combination (in this case font ID).

I use the technique described by Carpetsmoker, but I didn't like the fact that the PHP script is invoked every time. On Apache, you can set the following rewrite rule (in .htaccess):
RewriteCond %{REQUEST_URI} ^/css/cache
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^css/cache/(.*)$ /css/csscacher.php?files=$1 [L]
So say a request comes in for /css/cache/file1.css-file2.css, Apache will test for its existence. If it doesn't exist, the request will be forwarded to the csscacher.php script with the filename passed as the value of the "files" param. csscacher.php will load and combine the multiple files, send the result to the browser, but also write the result to /css/cache/file1.css-file2.css. All subsequent requests will be served as a static file.
To clear the cache, you'd just delete everything in the /css/cache folder. csscacher.php will recreate them from the source files as requests come in. More detail here.

You could also just use
#import url('reset.css');
at the top of your main css fiel to import other css files on the fly.

Have a look at the Google minify project. It offers a good solution to combine and also compress your JavaScript or CSS files. It is a PHP library that you can set up on your webserver with a script that takes a list of JS or CSS files and outputs a concatenated version. It also caches the result.

The implementation could be separated into three steps. Firstly, define a control wraps all the reference JS files.
Secondly, during the rendering of that control, using any kind of algorithm (e.g. encoding / encrypting) for all file paths to a string, and generate the script tag with a src which points to a certain handler with that generated as querystring.
e.g. Image we have two files: a.js and b.js, we have a control wraps them and generates the script tag like:
<script type='text/javascript' src='/js.php?include=encodeab'></script>
Thirdly, when client side displays the html page and sends request for that script tag, a certain server side handler (js.php in above case) will decode / decrypt that querystring to a list of included files, then read content of them, combile together and output to stream.
Hope this helps.

Be wary using dynamic js or css files as you may accidentally force the user to download them on each page (instead of using browser caching).
You can include multiple javascript/php files into one file, then give it a header of type javascript:
header("Content-type: text/javascript");
include('javascript1.php');
include('javascript2.js');
The same holds true for CSS.
Resources:
http://www.javascriptkit.com/javatutors/externalphp.shtml
http://www.webmasterworld.com/php/4239826.htm

You can use something along the lines of:
<?php
header('Content-Type: text/css');
if (isset($_GET['files']))
{
$files = explode(',', $_GET['files']);
foreach ($files as $file)
{
# BEWARE!
# What happens if the file is ../../../../../../../../etc/passwd?
$file = str_replace('..', '', ltrim($file, '/'));
include($file);
}
}
?>
test.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="css.php?files=style1.css,style2.css" />
</head>
<body>
<h1>This should be red</h1>
<p>red border</p>
</body>
</html>
style1.css
p { border: 1px solid red; }
style2.css
h1 { color: red; }
This is a simple example, you can easily expand it to allow javascript files. Another good optimisation would be setting the Last modified headers based on the mtime of the .css files (use stat()) ... But the general idea should be clear.
BEWARE, to be honest, I'm not sure if the escaping/parsing of the $_GET['files'] is enough ... Please research this topic to be sure, this can a very dangerous security problem :-)
Hope this is enough to get you in the right direction.

You can do something close by calling a dynamic JS file:
start with a php file and then in it:
<?php
if(isset($_GET['jsOne'])){
include'example.com/js/one.js'; // points to some .js file
}
if(isset($_GET['jsTwo'])){
include'example.com/js/two.js'; // points to some other .js file
}
if(isset($_GET['jsThree'])){
include'example.com/js/three.js'; // points to yet a another .js file
}
?>
and in the header just have:
<script type="text/javascript" src="js/allScripts.php?jsOne=yes&jsThree=yes"> and so on
Hope this helps.

Related

PHP Require method doesn't show any CSS style

I'm recently doing a website for a school project. In order to organize my work, I create a tree folder that keeps all the work organized. It is similar like this:
Back-Office
Pages
Home
home_test1.php
home_test2.php
home_test3.php
Login
Folder_Login
login.php
logout.php
Resources
CSS
style_home.css
style_navbar.css
style_footer.css
JS
script_home.css
script_navbar.css
Sections
navbar.php
footer.php
After all, with the require() method available in PHP, I want to call the "navbar.php" file to the "home_test1.php", "home_test2.php" and "home_test3.php", but the CSS style that is connected with the file "navbar.php" ("style_navbar.php"), doesn't display.
I've tried to change the path of the CSS style in the file "navbar.php" when I require() to the other file ("home_test1.php") and the CSS style shows up, but wont display in other file with a different path. How can I make this work dynamically? Sorry for long post and bad English grammar.
Thank you in advance.
You need to set your css and js files with absolute path instead of relative path
$dir = realpath($_SERVER["DOCUMENT_ROOT"]);
<link rel="stylesheet" href="<?php echo $dir.'/resources/css/style_home.css'; ?>" >
Without physically seeing you code it is quite hard to debug however there is an "obvious" answer that I'll suggest as a starting point.
The important thing to remember is that PHP and HTML are processed in completely different places. PHP executes on the server and should be used to build a full HTML "document" which it gives to the client/browser. The client/browser then reads the document provided and renders it according to HTML standards.
Calling require() will tell PHP to get the file and slot its contents directly where it was called and as it is a CSS file it will need to sit within the style tags. With a lot of modern browsers, if you use require on a file outside of the html tags, the content will be dumped at the top of the screen or simply ignored due to invalid syntax.
Alternatively if you would like to simply use tell the browser to include the CSS file, you could use the good old method of using <link rel="stylesheet" href="/path/to/file">. It's good to know when and when not to use PHP.
PS: You have .css files in your JS directory.
In PHP, there is a global variable containing various details related to the server. It's called $_SERVER. It contains also the root:-
$_SERVER['DOCUMENT_ROOT']
<?php
$path = $_SERVER['DOCUMENT_ROOT'];
<link rel="stylesheet" href="<?php echo $path.= '/Resources/CSS/style_navbar.css';?>" />
?>

Detect if php file is being used in <link> or <script> tag

I have a PHP file called styles.php?id=1. This fetches CSS code from MySQL and using Content-type: text/css. It can be used with <link> tag.
If I use .htaccess to rewrite engine, then it would be /styles/1. I have a similar file which fetches js (/scripts/1) code instead.
Instead I want one file called code.php which can detect which tag it is being used in and fetch the code from the database.
It's impossible. HTTP request to your server does not contain the tag that caused it.
The only way is to include what you want into GET.
Pseudocode:
if (isset($_GET['js'])) {
echo (getJavascriptFromDB());
} elseif (isset($_GET['css'])) {
echo (getCSSFromDB());
} else {
die("Invalid");
}
HTML:
<link href="code.php?css=1" rel="stylesheet" />
<script src="code.js?js=1"></script>
It has been quite a while but I got an answer. Just thought to share it with other people who need something similar to this.
In .htaccess
RewriteEngine On
RewriteBase /
RewriteRule ^code/(\w+).(\w+)$ code.php?id=$1&type=$2
And In PHP, I would check if the parameter type is equal to CSS or JS and set the content-type header

How to reconcile gzip compression and the flushing of the header of index.php

I have a pretty big index.php file(about 500kB) in which lots of logic and database query are present(and the index.php which goes to the client is about 200kB). What I'd like to do is first of all compress the file using gzip, which I do by simply adding SendOutputFilter in my .htaccess file. Now, since the file is pretty big to process for the server, TTFB can take a while and therefore I'd like to send to the user the header of the file before even looking at the query so that the browser will discover images, css and js(which are also pretty big) and will start downloading instead of being idle waiting for the whole index.php being processed on the server (I'd like something like Google search does. It starts download pngs before the whole page is loaded(and the page is compressed)).
I made some query and I couldn't find any straightforward solution. All I found is that either I disable gzip and use flush or use gzip but not flush.
But as you can see in my case I need both, and I know this can be done somehow. Possibly with some workarounds.
This is how huge modern websites already do, so I'd like to know how.
Luckily I was wrong. Even though GZIP needs to be downloaded completely before you can unpack it, you dont have to send just one chunk. You can send several seperate chunks, where each one is encoded separately.
This means the browsers needs to download chunk one completely and then it can unpack it and start parsing the html. Meanwhile it is downloading chunk two.
Progressive rendering via multiple flushes is a nice article explaining how it works. It is however not PHP handled, but server/apache handled.
Check out How to make PHP generate Chunked response for the PHP part you need to do.
To make GZIP work is related to how your server is setup, for help your best bet would be serverfault
This doesn't address the issue of GZIP and flush but rather PHP script and page design tailored for your question about preloading css, html etc.
You may want to consider splitting your index.php workload between two scripts, first loading html for display purposes and then then requesting the "heavier" tasks asynchronously using ajax, subsequently updating portions of your screen.
This will allow CSS and all the rest to do their work first followed by longer running tasks to display their results later.
To accomplish this start of with a "lightweight" index.php file with basic webpage html and display logic, with a event/trigger like $(window).load(function(){ //ajax call to heavier heavy_index.php script and screen updating from response }) which would allow the page to render completely and then once loaded call the heavier stuff.
This gives a quick example:
index.php
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/my_css.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript">
$(window).load(
function () {
alert("About to load more content");
$.ajax({
url: "/heavy_index.php",
success: function (html_data) {
$("#content_loaded_later").html(html_data);
}
});
});
</script>
</head>
<body>
<div class='content_initial' ><span>Content initially loaded</span></div>
<div class='content_later' id='content_loaded_later'>loading...</div>
</body>
</html>
heavy_index.php
<?php
echo "resulting content from heavier workload";
?>
my_css.css
.content_initial
{
border:1px solid red; width:120px; height:120px;
margin:10px;
}
.content_later
{
border:1px solid green; width:120px; height:120px;
margin:10px;
}
You may also want to look at this post Preload CSS/Javascript without Execution
Hope this helps at all.
As far as I know, there is no way within Apache to force early output of content to the browser. However it is possible to do so from PHP. Note that in PHP output buffers can be layered, hence you may need to....
while (ob_get_level()) ob_end_flush();
This will send the data back to Apache without closing stdout. In the absence of other complications, that will trigger a chunked response to the browser. But the mod_deflate output filter also buffers data - DeflateBufferSize - 8kb by default. If your <head> (NOT YOUR HEADER!) is more than this size it will sit in the buffer until it is pushed out by more content. You can reduce the size of the buffer and you can pad your content to fill it - in practice you should be using both methods.
Since other people have said that this is impossible (it is not - try it) and described using Ajax to load the page, you might want to take a look at PJAX. There are big adavantages to using this on very javascript heavy site.

How to set background-image using img tag

I have a php method such that it will return an html IMG tag.For example ImageClass::getImage('sample.png' , 'myTilte') will return a string as <img src="sample.png" title="mtTilte" />
In my css file there is place I used
div.error {
background-image: url('sample.png');
background-repeat: no-repeat;
}
How I use ImageClass::getImage method to instead of url() method in css for background-image.
I'd probably avoid putting php script in your stylesheet if at all possible. But if you really want to, you'll need to let the server know to either
Interpret what your PHP outputs as a stylesheet
Execute PHP script in your CSS files
Both of these have been answered a few times across the web and here on StackOverflow, so my answer isn't anything groundbreaking. But I'll repeat the answer for the sake of completeness:
Interpreting PHP output as a stylesheet
Begin by linking a .php file instead of a .css file. Then set the Mime type in your PHP file so its output is interpreted by the server as CSS. In code lingo, that would look like this:
HTML
<link rel="stylesheet" href="style.php">
PHP
Put the following code before any text output:
header("Content-type: text/css");
Executing PHP script within a .css File
The other method requires some server configuration. On Apache, the easiest way would be adding this to an .htaccess file:
AddType application/x-httpd-php .css
This will cause Apache to do the same thing it does inside .php files inside your .css files: namely, look for PHP script and execute it.
you could simply do the CSS inline.
<?php
$image = ImageClass::getImage('sample.png','myTitle');
$bg_img = explode(" ",$image);
$src = substr(strpos('"',$bg_img),strlen($bg_image)-1);
echo "<div style='background-image: url(".$src.");' ></div>
I couldn't test this, but I'm sure you get what I mean :)

Multiple javascript/css files: best practices?

I have about 7 Javascript files now (thanks to various jQuery plugins) and 4-5 CSS files. I'm curious as to what's the best practice for dealing with these including where in the document they should be loaded? YSlow tells me that Javascript files should be--where possible--included at the end. The end of the body? It mentions that the delimeter seems to be whether they write content. All my Javascript files are functions and jQuery code (all done when ready()) so that should be OK.
So should I include one CSS and one Javascript file and have those include the rest? Should I concatenate all my files into one? Should I put Javascript my tags at the very end of my document?
Edit: FWIW yes this is PHP.
I would suggest using PHP Minify, which lets you create a single HTTP request for a group of JS or CSS files. Minify also handles GZipping, Compression, and HTTP Headers for client side caching.
Edit: Minify will also allow you to setup the request so that for different pages you can include different files. For example a core set of JS files along with custom JS code on certain pages or just the core JS files on other pages.
While in development include all the files as you normally would and then when you get closer to switching to production run minify and join all the CSS and JS files into a single HTTP request. It's really easy to setup and get working with.
Also yes, CSS files should be set in the head, and JS files served at the bottom, since JS files can write to your page and can cause massive time-out issues.
Here's how you should include your JS files:
</div> <!-- Closing Footer Div -->
<script type="application/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.1.min.js"></script>
</body>
</html>
Edit: You can also use Cuzillion to see how your page should be set up.
Here's what I do: I use up to two JavaScript files and generally one CSS file for each page. I figure out which JS files will be common across all of my pages (or enough of them so it's close - the file containing jQuery would be a good candidate) and then I concatenate them and minify them using jsmin-php and then I cache the combined file. If there are any JS files left over that are specific to that one page only, I concatenate, minify, and cache them into a single file as well. The first JS file will be called over a number of pages, the second only on that one or maybe a few.
You can use the same concept with CSS if you like with css-min, though I find I usually only use one file for CSS. One thing extra, when I create the cache file, I put in a little PHP code in the beginning of the file to serve it as a GZipped file, which is actually where you'll get most of your savings anyways. You'll also want to set your expiration header so that the user's browser will have a better chance of caching the file as well. I believe you can also enable GZipping through Apache.
For the caching, I check to see if the file creation time is older than the amount of time that I set. If it is, I recreate the cache file and serve it, otherwise I just get the existing cached file.
You haven't explicitly said that you've got access to a server-side solution, but assuming you do, I've always gone with a method involving using PHP to do the following:
jquery.js.php:
<?php
$jquery = ($_GET['r']) ? explode(',', $_GET['r']) : array('core', 'effects', 'browser', 'cookies', 'center', 'shuffle', 'filestyle', 'metadata');
foreach($jquery as $file)
{
echo file_get_contents('jquery.' . $file . '.js');
}
?>
With the snippet above in place, I then call the file just like I normally would:
<script type="text/javascript" src="jquery.js.php"></script>
and then if I'm ever aware of the precise functionality I'm going to need, I just pass in my requirements as a query string (jquery.js.php?r=core,effects). I do the exact same for my CSS requirements if they're ever as branched.
I would not recommend using a javascript based solution (like PHP Minify) to include your css as your page will become unusable if the visitor has javascript disabled.
The idea of minifying and combining the files is great.
I do something similar on my sites but to ease development I suggest some code which looks like this:
if (evironment == production) {
echo "<style>#import(/Styles/Combined.css);</style>"
} else {
echo "<style>#import(/Styles/File1.css);</style>"
echo "<style>#import(/Styles/File2.css);</style>"
}
This should let you keep your files separate during dev for easy management and use the combined file during deployment for quicker page loads. This assumes you have the ability to combine the files and change variables as part of your deploy process.
Definitely look into including your js at the bottom and the css at the top as per YUI recommendations as keeping the JS low has a tangible affect on the appearance of the rest of the page and feels much faster.
I also tend to copy+paste all of my jquery plugins into a single file: jquery.plugins.js then link to
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js">
for the actual jquery library.

Categories