HTTP Headers and the PHP header() Function


Many beginning and intermediate PHP programmers seem to think the header() function
is some kind of strange voodoo. They work from examples and code snippets and are able to get things done with it,
but they don’t know quite how it works. That was certainly the
way I regarded header() the first time I saw it.

In reality, it’s quite simple. In this tutorial, I’ll explain a little about how HTTP headers work, how they relate to PHP,
and a little about their meta tag equivalents.

Hopefully by the time you’re done reading this, you’ll feel more confident about how to
use the header() function, and even have some new ideas about how it can help you. We’ll also cover some other important
topics related to HTTP headers and PHP. Before we talk about any programming
at all, though, we need to quickly (and incompletely) go over how HTTP (HyperText Transfer Protocol) works in general.

HTTP Overview

Headers: words in a conversation

HTTP is the protocol (the set of ‘rules’) for transferring
data (e.g. HTML in web pages, pictures, files) between web servers and
client browsers, and usually takes place on port 80.
This is where the ‘http://‘ in website URLs comes from.

The first time most people make a web page, they write the HTML on their computer, view it locally in a browser,
upload it to their server, and view it on the web. It might seem like viewing a page locally and viewing it on the server
is exactly the same, and that the only data going back and forth between the server and the
browser is the HTML and any images included in the page. But there is actually a lot of other information that you do not
see when you view a file on the web — the headers.

Headers can be separated into two broad types: Request headers that your browser sends to the server when you request a file, and
Response headers that the server sends to the browser when it serves the file. Think of these headers as the words in a
conversation taking place between the browser and the server. I like to imagine the server as a librarian, and the browser as a
researcher asking for a library resource. The browser walks up to the server at the main desk (port 80) and says
something like, “Hi, my name
is Mozilla, and I’m looking for the resource with the call number ‘’. Can you get it for me?” The server listens, and responds “Yes, I found it, let me send it to you. The data in the item is HTML text, and it says ‘<html>…'” The browser reads through, and comes to an image tag, and asks the server for item with the location in the src attribute. The server looks, finds the file and says “This file is a PNG image, and the data is….” You get the idea.

Another conversation might go like this:

Browser: Hi, I’m Mozilla, can I have the file at ‘’?
Server: That file is no longer there, it is at ‘’.
Browser: Hi, I’m Mozilla, can I have the file at ‘’?
Server: I found the file. Look at it for 10 seconds and then ask me again. It’s HTML text and it reads….
…10 seconds…
Browser:> Hi, I’m Mozilla, can I have the file at ‘’?
Server: I found the file. Look at it for 10 seconds and then ask me again. It’s HTML text and it reads….
…10 seconds…
Browser: Hi, I’m Mozilla, can I have the file at ‘’?
Server: I found the file. Look at it for 10 seconds and then ask me again. It’s HTML text and it reads….
….and so on, until the browser is redirected by the user….

As you can see, there is a lot going on that headers control. Using the header() function, you can make the
server send any headers that you need want, which allows you to do some really cool things beyond just sending plain old HTML.

Seeing the whole conversation

Before moving ahead, let’s get a better idea of how HTTP headers work by viewing a webpage without a browser, so we can
see the converation in is entirety. Start by opening a command prompt (in windows, go to Start->Run, type cmd, and click “OK”…if you’re using linux you probably already know). At the prompt, type:

telnet 80

and press Enter. This will connect you to on port 80. Next, copy and paste just the text below:

GET / HTTP/1.1

Don’t worry if when
you type or paste the text, it does not show up in your command window and all you see is the cursor — it is indeed being sent to the server. The first line says you are using the GET request method to get the resource /
(i.e. the file in the base directory of the host), and that you are using HTTP version 1.1. The second tells the server which host
you want to connect to. When you finish typing ‘’, hit Enter twice (and twice only). You should almost immediately get a response that looks like:

HTTP/1.1 301 Moved Permanently
Date: Wed, 08 Feb 2006 07:44:07 GMT
Server: Apache/2.0.54 (Debian GNU/Linux) mod_auth_pgsql/2.0.2b1 mod_ssl/2.0.54 OpenSSL/0.9.7e
Content-Length: 233
Content-Type: text/html; charset=iso-8859-1

<title>301 Moved Permanently</title>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="">here</a>.</p>

Whoops! Looks like we requested a resource that wasn’t there; it’s been permanently moved to the new Location If you were using a browser, you’d only see the HTML — everything before the first blank
line is the headers. In fact, modern browsers are even smarter than that — when they see the Location header on the
third line, they automatically go there so you don’t have to type in a new URL. Let’s go to the new URL. By this point, you
probably got disconnected while you were reading this. If so, just press your up arrow on the keyboard to get your telnet command back, and press enter to reconnect. If you’re still connected, you can just go ahead and type the following:

GET / HTTP/1.1

and press Enter twice after the second line. You’ll get another similar response telling you that the page is actually at The server is particular, isn’t it? 😉 Repeat the above, but this time type

GET /index.php HTTP/1.1

Notice that the name of the file we want is in the first line. This time we get flooded with text: the HTML from ERT’s homepage.
The headers look like

HTTP/1.1 200 OK
Date: Wed, 08 Feb 2006 08:20:07 GMT
Server: Apache/2.0.54 (Debian GNU/Linux) mod_auth_pgsql/2.0.2b1 mod_ssl/2.0.54 OpenSSL/0.9.7e
X-Powered-By: PHP/4.4.0
Transfer-Encoding: chunked
Content-Type: text/html

Simple, no?. Let’s move forward and see how this relates to your programming.
Don’t worry if you didn’t understand every single thing
that we just did. The important thing is to have a general feel for how the browser and server talk to each other,
and to realize that there is nothing magic about it. The take home points are:

  • The browser and the server talk to each other using headers
  • Headers are sent before the main content, and are separated from the main content by a a
  • In the header section, there is one header per line. The name of the header comes first, followed by a colon and a space, followed by the content/value of the header:
    Header-Name: header-value
  • Headers can contain many types of information and instructions that the server and browser use to help each other know
    what to do next

Note: If you’re the type who likes to really dig into the details, you can look at
RFC 2616 for the complete HTTP/1.1 specification in all its glory.
In particular, Section 14 offers a complete
definition for each header field.

PHP header(): The Basics

Notice the response headers X-Powered-By: PHP/4.4.0 and Content-Type: text/html that were
returned when we
finally got to the homepage. PHP was designed from the beginning to output HTML (the ‘H’ in PHP stands for ‘Hypertext’), and
the first time a script generates output (e.g. by using echo), PHP automatically includes those headers for you. This is
very convenient, but also contributes to the confusion many PHP beginners have regarding headers — in more ‘bare bones’
languages like Perl that were not originally designed for the web, sending output without including your own headers produces
the dreaded ‘500 Internal Server Error’, so Perl web
programmers have no choice but to learn about headers immediately.

The header() function sends HTTP response headers; nothing
more, nothing less.

Using this function, you can make your scripts send
headers of your choosing to the browser, and create some very useful and dynamic results. However, the first thing you need to know about the
header() function is that you have to use it before PHP has sent any output (and therefore its default headers).

I doubt there is a PHP programmer in the world who has never seen an error that looks like

Warning: Cannot modify header information – headers already sent by…..

As we said above, the response headers are separated from the content by a blank line. This means you can only send them once, and if
your script has any output (even a blank line or space before your opening <?php tag), PHP does so without asking
you. For example, consider the script below, which seems logical enough:

Welcome to my website!<br />



"You're in!";






What this script is trying to do is redirect the visitor using the Location header if
$test is not true. Do you see the problem? The ‘Welcome…’ text gets sent no matter what, so the headers are
automatically sent. By the time header() is called, it’s already too late: instead of getting redirected,
the user will just see an error message (or if you have error reporting off, nothing but the ‘Welcome…’ text).

There are basically two solutions to this. The first is to rewrite the code



'Welcome to my website<br />You're in!';






The second is output buffering, which can be somewhat more elegant and easy to use.
In our example above, rewriting the code wasn’t much trouble, but imagine if there had been quite a bit of
HTML to move around — it could be pretty cumbersome, and it might make our code harder to follow. While our first example caused an error, the logic of the program was fine. Output buffering allows you
to hold on to (‘buffer’) output (even HTML outside of PHP code tags) and send it to the browser only when you explicitly say to do
so. This way you can program however you would like to, and explicitly send the output after you’ve specified any headers you need to. The two relevant functiosns are
ob_start(), which turns output buffering on, and
ob_flush(), which sends the content that has accumulated
in the buffer:


();  //begin buffering the output 


Welcome to my website!



"You're in!";





  ob_flush(); //output the data in the buffer


I encourage you to read more about all of the output buffering functions, which can be quite useful. You should flush the output
buffer as soon as possible, especially if you have quite a bit of content to send. Otherwise, your page will appear to load
slower, becuase the content will be sent only after it has been entirely assembled, rather than as it is available.

Note: The 2nd argument If you call header() more than once for the same header field, the value for that header will
be the one included in the last call you made. For example,


('Some-Header: Value-1');

header('Some-Header: Value-2');


would produce the header Some-Header: Value-2. You can cause both headers to be sent by using the second replace argument
for header, which is true by default. If you set this to false, the second header value will not replace the first,
and both will be sent. So the code


('Some-Header: Value-1');

header('Some-Header: Value-2'false); //don't replace the first value


will produce the header Some-Header: Value-1, Value-2. You will rarely need this, but is good to know.

Armed with a good understanding of how HTTP headers and PHP work together, let’s look at some specific examples of using this

PHP header(): Some Examples

Note: The code snippets appearing below are just that: snippets from
complete working code. When you you include them in your own programs, remember to define all your variables,
assign default values, and adhere to other good programming practices.

Redirecting with the Location header

We’ve seen this one a couple times above: it redirects the browser.


('Location: http/');


While you can somtimes get away with supplying a relative URL for the value, according to the HTTP specification, you should
really use an absolute URL.

One mistake that is easy to make with the Location header is not calling
exit directly afterwards (you may not always want to do
this, but usually you do). The reason this is a mistake is that the PHP code of the page continues to execute even though the user
has gone to a new location. In the best case, this uses system resources unnecessarily. In the worst case, you may perform tasks that
you never meant to. Consider the code below:


//Redirect users with access level below 4

if (check_access_level($username) < 4){



//Mail users with higher access level the secret code


echo 'The secret email is on its way!';


Unauthorized users are indeed redirected, but in fact, they too will receive the email, because the script continues to run.
To avoid this, the part for authorized users could be wrapped in an else{} statement, but it is cleaner and easier
to call exit immediately after the header command to end the execution of the script:


//Redirect users with access level below 4

if (check_access_level($username) < 4){


//stop script execution


//Mail users with higher access level the secret code


'The secret email is on its way!';


Redirecting with the Refresh header

The Refresh redirects users like the Location header does, but you can add a delay before the user
is redirected. For example, the following code would redirect the user to a new page after displaying the current one for 10


('Refresh: 10; url=');

'You will be redirected in 10 seconds';


Another common application is to force a page to update repeatedly by ‘redirecting’ to the current page (see the second
‘conversation’ above). For example, here is a simple page that will ‘count’ down from 10, with a 3 second
pause between numbers:



$_GET['n'] = 10;


if($_GET['n'] > 0){

header('Refresh: 3; url=' $_SERVER['PHP_SELF'].'?n=' . ($_GET['n']-1)  );

  echo $_GET['n'];






Note: If the refresh time is set to 0, then the Refresh header is
effectively the same as the Location header.

Serving different types of files and generating dynamic content using the Content-Type header

The Content-Type header tells the browser what type of data the server is about to send. Using this header, you can
have your PHP scripts output anything from plain text files to images or zip files. The table below lists frequently-used
MIME types:

You can do several interesting things with this. For example, perhaps you want to send the user a pre-formatted text file
rather than HTML:


('Content-Type: text/plain');



Or perhaps you’d like to prompt the user to download the file, rather than viewing it in the browser. With the help of the
Content-Disposition header, it’s easy to do, and you can even suggest a file name for the user to use:


('Content-Type: application/octet-stream');

header('Content-Disposition: attachment; '




Maybe you need to serve a file for download, but you’d like to obscure its true location and name, and only serve it to users
who are logged in:



header('Content-Type: application/octet-stream');

header('Content-Disposition: attachment; ' 


readfile('/path/to/files/' $filename);



'You are not authorized to view this file';



Perhaps you’ve dynamically generated an image using PHP’s image functions and you want to display it to the user. You could create a file build_image.php like this

Common MIME types
Type Description
text/html HTML (PHP default)
text/plain Plain Text
image/gif GIF Image
image/jpeg JPEG Image
image/png PNG Image
video/mpeg MPEG Video
audio/wav WAV Audio
audio/mpeg MP3 Audio
Quicktime Video
video/x-ms-wmv Windows WMV video
audio/x-ms-wma Windows WMA audio
audio/x-realaudio RealPlayer Audio/Video (.rm)
audio/x-pn-realaudio RealPlayer Audio/Video (.ram)
AVI Video
application/pdf PDF Document
application/msword MS Word .doc file
application/zip Zip File
application/octet-stream Misc. data. Use to force download or open with application.*
x-foo/x-bar Misc. data. Use to force download ot open with application.*


//build the image above

header('Content-Type: image/jpeg');



Note: Beware of magic_quotes!
PHP’s automatic escaping of special characters with a backslash may seem like a good idea at first, but most good programmers
generally agree that it (a) encourages sloppy programming that does not validate input and (b) causes
annoyances in well-written code that would not occur if “magic quoting” were turned off. One such annoyance is
the corruption of binary data. In the example above, if
is on, the data that readfile() outputs may have backslashes added to it, thus
corrupting the file that is sent to the user. Ideally, you should turn magic_quotes_runtime off in your
php.ini file to avoid this, but if you do not have access to the configuration file, you can also use the
set_magic_quotes_runtime() function
(pass is the 0 (zero) integer) to turn the setting off.

Happily, the minutes of a recent
PHP Developer meeting show that they have decided to abandon magic quotes in future versions (6+) of PHP. Until
everyone upgrades, however, keeping the problems this feature can cause in mind can save you quite a bit of
trouble and frustration.

You might pass the parameters necessary to generate the image via the URL so you can access them in the $_GET array.
Then in another page, you might include this image using an img tag:

<img src="build_image.php<?php echo "?$user_id&amp;$caption"?>">

The possibilities are more or less endless. The more PHP programming you do, the more you will find that the Content-Type
header truly is your friend.

Note: The way that browser are supposed to handle content of various MIME types, and the way they actually do
may not always be consistent (especially with Internet Explorer), so you’re well-advised to test your pages in the browsers
you need to support to make sure they behave as expected. The PHP Manual has many helpful tips in the
on the header() page.

Preventing Page Caching

PHP pages often generate very dynamic content, and to prevent users from missing updates by viewing cached pages, it is
often helpful to be able to tell browsers not to cache certain pages. The following snippet works quite well on the
browsers that are likely to visit your site:


('Cache-Control: no-cache, no-store, must-revalidate'); //HTTP/1.1

header('Expires: Sun, 01 Jul 2005 00:00:00 GMT');

header('Pragma: no-cache'); //HTTP/1.0


The Expires header can be any date in the past. As with MIME types, browsers (especially older ones) may not
always listen properly to your caching instructions (although most modern ones will).

Other Applications

There are other ways you can use headers as well, such as setting the
HTTP Response Code, or in performing
HTTP Authentication (if you are running PHP as an Apache module).
Now that you understand how header() works and how to use it, you’ll be able to do all sorts of things you
might not have thought of before.

Request Headers in PHP

We’ve covered some of the things you can do with response headers above. We can also get a great deal of information
from the request headers received by the server from the browser. There are two ways to access these. First, many of the
values in the $_SERVER array are determined from the
request headers. Second, if PHP is installed as an Apache module, then
apache_request_headers() will return an
array of all request headers (even those not in $_SERVER).

Security first: don’t trust request headers

Since request headers are set by the browser, which is controlled by the client, you must never trust request
headers for information that is important to the security of your site
. A good example is the
$_SERVER['HTTP_REFERER'] variable, which should hold the URL of the page that referred the
user to the current one. A common mistake among beginners is to think that they can use this to make sure
that users only access pages through a certain path, and that they therefore do not need to
worry about server side data validation. For example,
consider this code, which attempts to make sure that data has been submitted from a specific page, rather
than a custom form on another website:


if($_SERVER['HTTP_REFERER'] != ''){

header('Refresh: 5; url=');

'You must use the form on my site...redirecting now.';



   insert_data($_POST['var1'], $_POST['var2']);



This might work to deter an unsophisticated hacker who is using his web browser to submit data through a custom form, but someone
who is a little more savvy could easily submit data via a telnet session like we did above, including the request header

and easily defeat this ‘protection’. The moral of the story is: use HTTP request headers to gather statistics and to help make
the user experience more pleasant — most request headers you receive will be supplied by standard browsers and will be
entirely truthful…But do not rely on request headers for any issues pertaining to security.

Using HTTP request headers

There are several things you can do with these. Using $_SERVER['HTTP_USER_AGENT'] you can detect the type of browser
the user says it has. You might check the $_SERVER['HTTP_ACCEPT_LANGUAGE'] (perhaps along with $_SERVER['HTTP_ACCEPT_CHARSET'] and some
IP address geolocation) to help determine the
best language in which to serve your pages to a given user.
Although $_SERVER['HTTP_REFERER'] is not reliable for security
purposes, it could be useful as an aid for building statistics about your website traffic or customizing content to
match the path the user took to reach a given page. If for some reason you want to manipulate the raw query string used when
the page was accessed, you can look in $_SERVER['QUERY_STRING']. Looking in $_SERVER['REQUEST_METHOD'] will
tell you whether your page was accessed via GET or POST. There’s quite a bit of information there for
you to find creative uses for.

HTML Meta Tag HTTP Header Equivalents

Chances are, before reading this article, you have seen or used the HTML meta tag below to redirect a user:

<meta http-equiv="refresh" content="0;" />

Look familiar? The ‘http-equiv’ meta tags are ‘equivalent’ to HTTP response headers, and were introduced so that people
writing HTML pages without server side programming would have access to the powerful functionality described above. Using these
meta tags is simple: they can be placed anywhere in the <head> of the document, and their http-equiv
attribute contains the header name, while the content attribute contains the value for the header.

I’ve found that these, like the HTTP headers in general, often produce confusion, but now they should seem quite simple to you.
Although I usually prefer to use the PHP header() function, these meta tag HTTP header equivalents are often very handy
for things like specifying the character set. For example, I often use this is my HTML pages (and sometimes my PHP ones):

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
Note: Support for HTTP headers as equivalet meta tags is not uniformally supported, so it is usually safer and
faster to use the headers themselves if you can. Also, it should be obvious that some headers and values will not work as meta
equivalents: you cannot set the Content-Type to image/png when the real headers have been sent and the
browser is already reading the HTML 😉


Now that you are done with this article, you should have a pretty firm grasp of how HTTP works, how request and response headers
are used, and how you can employ this functionality in your programming. This reasonably detailed knowledge should also enable
you to start thinking more critically about your web application efficiency and security. I hope that as you move forward with your
programming, you will find that you’ve become quite comfortable working with HTTP headers, and that you are able to exploit them to
make your job easier and your pages better.

As a parting thought, remember that headers are like words: they convey information and ask for certain actions to be performed,
but by themselves they don’t force anything to happen. 99.9% of the time, cooperative browsers are talking to cooperative servers,
and everything happens smoothly. But you have to remember that, as in life, every once in a while you’ll run across a jerk
(a hacker), or someone who’s got his own way of doing things (Internet Explorer). Web development is very much a job of customer
service, so you’ve got to do your best to keep the crooks out, and accomodate the customers with ‘special needs.’ 😉


Zipped DOCX XML parse and delete commented block

$filename = ‘demo_ms_word.docx’;
$ext = end(explode(‘.’, $filename));
//if its docx file
if($ext == ‘docx’)
$dataFile = “word/document.xml”;
die(‘Wrong File’);

//Create a new ZIP archive object
$zip = new ZipArchive;

// Open the archive file
if (true === $zip->open($filename)) {
// If successful, search for the data file in the archive
if (($index = $zip->locateName($dataFile)) !== false) {
// Index found! Now read it to a string
$text = $zip->getFromIndex($index);

$document = new DOMDocument();
$xpath = new DOMXPath($document);

// Find the DIV with ID “some-div”.
$remove_elements = array();
$notfoundOnSameNode = true;

//From Condition Query found what elemenet need to delete
$tagToDelete = ‘tbl’;

$node = $xpath->query(‘//w:’.$tagToDelete.'[descendant::w:commentRangeStart[@w:id=”2″]]’)->item(0);
$remove_elements[] = $node;

$notfoundOnSameNode = false;

while ($node = $node->nextSibling) {
$remove_elements[] = $node;
//echo $node->nodeName;
//echo $node->nodeValue;
// Skip stuff like “#text” elements which cause problems.

//Delete all remove elmenets from docx
foreach ($remove_elements as $element) {

$final_xml = $document->saveXML();

//Write the new…
$zip->addFromString($dataFile, $final_xml);
//Close the archive file

How to check Field Value already exist in database with bootstrap validator

There are different validator available in bootstrap library . To check field value already exist in database or not . We can use remote validator of Bootstrap . Please check the following code of  sample registration form validate by bootstrap validator

By default, it is set to { fieldName: fieldValue } where fieldName and fieldValue are replaced with the field name and current value, respectively.

In some cases, you might want to send more fields with dynamic values to the back-end. For instance, the registration form need to validate both the username and emails.

The following sample code uses the data option showing how to do this:

<form id="registrationForm" class="form-horizontal">
    <div class="form-group">
        <label class="col-lg-3 control-label">Username</label>
        <div class="col-lg-5">
            <input type="text" class="form-control" name="username" />
    <div class="form-group">
        <label class="col-lg-3 control-label">Email</label>
        <div class="col-lg-5">
            <input type="text" class="form-control" name="email" />
    <div class="form-group">
        <label class="col-lg-3 control-label">Password</label>
        <div class="col-lg-5">
            <input type="password" class="form-control" name="password" />
$(document).ready(function() {
        fields: {
            username: {
                message: 'The username is not valid',
                validators: {
                    remote: {
                        url: '/path/to/backend/',
                        data: function(validator) {
                            return {
                                email: validator.getFieldElements('email').val()
                        message: 'The username is not available'
            email: {
                validators: {
                    remote: {
                        url: '/path/to/backend/',
                        data: function(validator) {
                            return {
                                username: validator.getFieldElements('username').val()
                        message: 'The email is not available'

Centering (horizontally and vertically) an image in a box

The problem

We want to center an image inside a container, bigger than the image and with assigned dimensions. The image is not a background one, it’s a true <img> element.

Any image has well defined dimensions, so the easiest and most reliable way to solve the problem is:

  • make the image display:block
  • assign to the image the needed left and top margins to get it centered in the container. Each of this margin value is obviously half the difference between a dimension of the container and that of the image.

For example if you have images of two different sizes, like in a photo gallery with “landscape” and “portrait” images, to be centered in fixed size containers, then assigning to each <img> one of two classes (with different margins) will solve the problem.

But there are cases when one does not want to use the previous method. For example when many images, all with different dimensions are involved and it is not practical to assign different margins to each of them, or when the dimensions of the container and those of the image are not expressed in the same units (px, em, %, …) hence the difference cannot be computed. It’s useful to have a different solution, independent on the image’s size.

A solution

The horizontal centering is not difficult. If the image is left with its default inline display, then text-align: center is the obvious solution, working well in all browsers.<!– And if the image is given display: block, then the usual method for horizontal centering of blocks can be applied, consisting in margin-left:auto; margin-right:auto (plus text-align: center on the container for IE5.x/Win.) –>

For the vertical centering the best solution, working in modern browsers, is to assign display: table-cell; vertical-align: middle to the container. This works in Gecko based browsers, Opera 6+, Safari, IE8. It leaves IE7 and lower (both Windows and Mac) out.

For IE7- the idea is to create a sort of line-box having as height the height of the container, and the using again vertical-align: middle. The line-height property cannot be used to achieve this, since it doesn’t work correctly in IE7-/Win in presence of images. Also the use of a big font-size (without specifying line-height) is problematic, because the height of the generated box is slightly bigger than the font-size. And IE5/Mac (differently from IE/Win) is able to resize (according to user choice) line-height and font-size expressed in pixels, so it would have problems with this approach, unless the height of the container is expressed in em. Note: this same argument precludes the general use of such vertical centering method, based on line-height, in Gecko based and Safari browsers.

Fortunately IE7- has (partial) support for display: inline-block. If an empty inline-block element (for example a span) is added inside the container and it is assigned height: 100%; vertical-align: middle then it allows to precisely get what we want: a line box with the desired height. In other words, the inline-block element respects an assigned height (equal to the container’s one) and props the line open, so that vertical-align: middle (both on the extra element and the image) gives the desired vertical centering.

Some details:

  • The extra, empty inline-block element may have zero width in IE7-/Win, but it must have at least width: 1px in IE/Mac, otherwise it has no effect (this sometimes offsets the horizontal centering by 1px. It could be counteracted with a -1px margin, but the problem is barely visible.)
  • In IE5/Mac the vertical centering is some pixels off. The use of a small font-size or line-height on the container seems beneficial, not clear why (IE5/Mac is a bit incoherent here, especially when playing with its font size settings.)

A combined solution, using display: table-cell and the extra span with display: inline-block, works in Gecko based browsers, Opera 6+. Safari, IE5+/Win, IE5/Mac.

A variation of this technique can be used to vertically center a block element (even with unknown height) inside another one (with known height) which is a more interesting problem.

The code

Putting all together, and naming “wraptocenter” the class of the container, that’s the relevant CSS. Code for IE/Mac is wrapped in a suitable filter. Code for IE7-/Win is put in conditional comments.

<style type="text/css">
.wraptocenter {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
    width: ...;
    height: ...;
.wraptocenter * {
    vertical-align: middle;
.wraptocenter {
    display: block;
.wraptocenter span {
    display: inline-block;
    height: 100%;
    width: 1px;
<!--[if lt IE 8]><style>
.wraptocenter span {
    display: inline-block;
    height: 100%;

And that’s the relevant HTML

<div class="wraptocenter"><span></span><img src="..." alt="..."></div>

SEO Friendly url using php and htaccess

This is the problem – you have a website or content management system that works happily, but the addresses that it produces are something like this:

This is fine – but have you considered the following:
1. This may not be the most search engine friendly address, particularly if it is long and unwieldy.
2. It is not so easy to give out specific addresses to people say for a conference or a specific project or product.
3. It could be more secure to prevent hacking such as SQL injection attacks etc.

So what could you do to improve the situation?

Two main things spring to mind – the quick way for starters would be to lose the page.php bit – this is quite straightforward. Here at EDinteractive, all the websites we develop use a content management system PHP CMS that produces friendly URL’s. If you are making your own solution however, you just need to do the following:

1. Create a folder called ‘page’ (or whatever you like)
2. Rename page.php to index.php and move this file into your newly created folder
3. Voila – your new address will now be:
That is a little bit better – but what if you wanted to lose those nasty question marks, ampersands and even numbers?

There are several ways to do this, but the one this article covers is to modify your .htaccess file for the website. If you do not have access to this file, or are unfamiliar with it – then this can open a can of worms – so here is a few simple things you can do to achieve completely friendly url’s using this method.

Using .htaccess to produce friendly url’s – Intro to .htaccess

The .htaccess file is a very powerful configuration file and should be used wisely as it can affect everything and anything about your website. First of all, check that you are able to create and use a .htaccess file on your site. On the root top level of your site, you should have this file and if not, you should be able to create a file in notepad and call it .htaccess. This in itself can be tricky – you need to make sure the file is called .htaccess and not .htaccess.txt or whatever. You can edit this file in Dreamweaver (or your editor) though if you like by right clicking it and choosing: Open with > Dreamweaver

Configuring .htaccess for friendly url’s

You need to put the following lines into your .htaccess file:

RewriteEngine On
RewriteRule /page/(.*)$ /page/page.php?id=$1

This basically tells your website that any request for your page should be re-written. Doing this will mean that your addresses will become further simplified to the following:

That is great isn’t it? Or is it? What happens if you have a conference or a product to promote – this address is still not friendly enough for your marketing campaign or to add more words into your search engine ranking – so how could you further improve this address? Here is one approach that you could use, but it involves a fairly serious change to your site, so think carefully before doing this.

Here comes the science – moving from id number identifiers to letters

This is the tricky bit. Your site so far has been using id numbers to identify its pages. The method covered in this article is going to change all that to use words to identify a record in the database. Firstly – create a new field in the database called something like page_address_identifier and set this to allow characters.
Each record in your database will then need some unique words to identify each record. So for example, page.php? id=3 was id 3 in the database, so I’ll add my new field to the database and set its value to be something like: contact_us
This identifier should use underscores_ instead of spaces and should ideally use lowercase characters a-z and/or 0-9. In the admin section of your site also – it may be a good idea to validate this field and check for duplicates to make sure your page_address_identifier’s are in the correct format and are unique.
You will also need to alter your SQL statement on page.php to select a record from the page_address_identifier field of your database and not the old id field.

Once this is done, it now means that:
can now be referenced as:
Not very friendly though is it?

That’s where the two techniques come together. Because of the changes you made to your .htaccess file earlier, you can now magically use this address:

Between the two techniques, contact_us is retrieved from the page_address_identifier field and .htaccess strips out page.php?id= 

That is the hard part done – you now have totally friendly url’s. There are yet more things you can do to make your addresses even more friendly if you so desire. Imagine for example you wanted this address:
This is quite possible, but again it could potentially open up a can of worms. In order to do that, you could change your .htaccess file to the following:

RewriteEngine On
RewriteRule (.*)$ /page/page.php? id=$1

Simple isn’t it? Well, actually, no it isn’t – you should now theoretically have this address:

But it doesn’t work for some reason – you will most likely get an internal server error, because this sends the server back and forth in an infinite loop. In order to get around this problem, you need to add this following condition to your .htaccess file before your rewrite rule:

rewritecond %{REQUEST_URI} !^/page/(.*)

This essentially allows the page folder to function. You’ll also have to add a line for each top level folder on your website that you want to allow e.g.:

rewritecond %{REQUEST_URI} !^/page/(.*)
rewritecond %{REQUEST_URI} !^/images/(.*)
rewritecond % {REQUEST_URI} !^/documents/(.*)


This article has covered several methods to make dynamic website addresses friendlier for your users and the search engines. There are obviously many ways you could do this, but your choice of method will ultimately depend on how brave you are feeling, what rights you have and how friendly you want your url’s to be. Modifying .htaccess can be a frustrating business at times to troubleshoot, but hopefully this article and the many others out there should help you achieve the addresses that you would like. If you would like to know more about this article or would like us to develop something for you,

Hide/Toggle submenu when clicking on another menu item

Just hide all li’s before toggling current li –

$(function () {
$('nav ul li').not("nav ul li ul li").click(function(e){
$("nav ul li ul").hide();
$("nav ul li ul li").click(function(e){
$(document).click(function() {
$("nav ul li ul").hide();

.htaccess, proper rewriting of directory and file with same name

There are two things going “wrong” here, and two ways to fix it.

The first is that apache “figures out” that there is a directory by the name of “portfolio” before the rewrite conditions are applied. That means that the rewrite conditions are receiving “portfolio/” instead of “portfolio”.

Second, the “!-d” rule is specifically avoiding the rewrite that you want to make if there is in fact a directory by that name

Solution 1: Manually re-route requests for the portfolio directory to remove the slash.

# Manually re-route portfolio/ requests to portfolio
RewriteCond %{REQUEST_FILENAME} portfolio/$
RewriteRule ^(.*)/$ $1 

# Hide extension
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html

Note the removal of the “!-d” condition.

The downside to this is that you are having to hard-code the “portfolio” edge case directly into the rewrite rules, and will still result in the browser being first redirected to portfolio/

Solution 2: Set DirectorySlash Off and remove directory exists test

# Disable Automatic Directory detection
DirectorySlash Off

# Hide extension
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html

Setting DirectorySlash Off would fix this issue the best, but may break other parts of your site where you actually want the auto DirectorySlash. Best of Luck, and I hope this helps.

Note when testing solution 2, your browser may remember the redirect of “portfolio” to “portfolio/” and perform the redirect before it even sends the request to the server. Be sure to test in a cache-clear, clean environment for best results.

Like Example :-

RewriteCond %{REQUEST_URI} !^/products/
RewriteCond "/products/" !-f
RewriteCond "/products/" !-d 
RewriteRule ^(.*)$ product.php [L,QSA]