Read The Anchor Part of The URL … with PHP

The Problem

Well usually the URL is formed like so – http://example.com/index.php#anchor1, if you have anchors, of course. And the problems is simple to define. With PHP you cannot grab the anchor part of the link (that anchor1 in the example). That’s of course normal behaviour, the anchors are used by the client (your browser usually) to position the page at a specific location, and being a client side technique is simple to guess that PHP cannot access them.

Why We Need Such a Thing?

Today the web is more and more full of such an Ajax rich applications, almost every one of them don’t refresh the page and use anchors to save the path of the user, and that’s how they manage the bookmarks of a specific state in the page. We often need this technique, cause every other change in the URL, but the anchors, invoke a reload of the page, which is bad. But however why don’t we use directly this anchors from the Ajax application? That’s because we’d like to speed up things. We load the page with an anchor in the URL, like so:

http://example.com/index.php#load-me-first

but in that case the page should load, than the JavaScript should grab the anchor, and than to process via Ajax request the data from the server … and even that is not enough, cause than the data should be placed on the right place in the page.

Note: In fact, most of the fully flash based sites work on the same schema.

We need the initial load to happen directly with PHP which is much more faster. But the problem is that, as I said PHP cannot read the anchor of the link. If you have http://example.com/index.php#load-me-first, none of the _SERVER variables will return the anchor, because as I noticed that’s client side issue.

The Solution

Well we need to combine the client and server side techniques to solve the problem. There comes JavaScript combined with PHP and all this is made with the help of the Cookies.

Let see the situation. If we have an anchor in the URL we can easily grab this with JavaScript:

<script>
 
var query = location.href.split('#');
 
</script>

Now the query[1] has the value of the anchor part of the URL. Now you can set this in a cookie.

<script>
 
var query = location.href.split('#');
 
document.cookies = 'anchor=' + query[1];
 
<script>

Note: it’s important to setup the cookie to be persistent only for this session so next time you enter the site there should not be such an existent one.

So far so good, what we need more is just to read that cookie in PHP, so you can put this PHP code above.

<script>
 
var query = location.href.split('#');
 
document.cookies = 'anchor=' + query[1];
 
<script>
<?php
 
echo $_COOKIE['anchor'];
 
?>

Of course, yes. This is not working correctly. In fact it’s working correctly from the second load on, but on the initial load of the page the _COOKIE array does not has any anchor key inside. That’s because this part of the code is executed before the browser setup the cookie on the client.

The Workaround

Well there is a workaround. You simply should wait for the cookie to come from the server. Like so:

<script>
 
var query = location.href.split('#');
 
document.cookies = 'anchor=' + query[1];
 
<?php if (!$_COOKIE['anchor']) : ?>
 
window.location.reload();
 
<?php endif; ?>
 
<?php
 
echo $_COOKIE['anchor'];
 
?>

Now everything is OK. You can parse the _COOKIE[‘anchor’].

Important

It’s exteamly important to put the <script> tag as high as you can, so the browser will setup and check for the cookie before anything is rendered to the page. In that case the reload of the page is so quick so you will not experience any delay at all.

30 thoughts on “Read The Anchor Part of The URL … with PHP

  1. Well there’s one question left. The above code is working fine when you open the url for the first time, i.e. http://example.com/index.php#load-me-first. So far so good, but what happens when I reload the content trough any other link in the page. I’ve the cookie set up now and the url’s changed like so : http://example.com/index.php#load-me-next. The problem comes when I refresh the page now. The cookie’s value is with the anchor of load-me-first, but the page is different (load-me-next anchor). So now there’s an issue. The content is loaded again as if it’s the first page load. The solution is to change a bit the condition:
    if (!$_COOKIE[‘anchor’])

    in the PHP. It should become a js condition:

    <script>
    if (query[1] != “< ?php echo $_COOKIE['anchor'] ?>“)
    ….

    Now the cookie is set, but is checked against the url anchor part. That should work properly.

  2. Интересно и позновательно, а будет еще что-то по этой теме?

  3. I’m having some trouble making the code you included in your post work when I try to integrate the additional changes to it you recommend in your blog comment.

    I don’t suppose you would mind either reposting the whole entire correct code snippet, or emailing that code to me? I’m really trying to get this to work on my site…

    Thank you!

  4. Here’s the code that worked for me

    query=location.href.split("#")
    document.cookie='anchor='+query[1];
     
    if (query[1] != "") {
        window.location.reload()
    }
     
    $passedaname=$_COOKIE['anchor']

    I had been trying to retrieve and process the data contained in a url hash with a php script, and stoimen’s script was the first thing I found that worked. Instead of echoing the $_COOKIE though, I passed it along to a php script, that’s the $passedaname var.

  5. Maybe this’ll work better

    <script language="javascript">
     
    query=location.href.split("#")
    document.cookie='anchor='+query[1];
     
    if (query[1] != "<?php echo $_COOKIE['anchor'];?>") {
        window.location.reload()
    }
     
    </script>
    <script language="php">
    $passedaname=$_COOKIE['anchor']
    </script>
  6. You may pass this value through AJAX, if we’re talking ’bout it. So actually php can read anchor only from preloaded page. What if i’m using URL with this anchor?

  7. Thanks for this tip, which i have already put to use. But I’m wondering if this redirect will mess up with search engines crawling through my site.

  8. @Griffith:
    at first sight using the parse_url() php functions sounds pretty easy,
    but there is a problem with getting $url part..
    Php just not able to process #hash anchor server-side because it is never tranferred to the server with normal http request. it is processed only inside user’s browser script engine and accessible via client-side scripts only.

    p.s. thanks Stoimen for this workaround.

  9. Grazie mille a tutti per le dritte su come fare, lavorandoci un pò su ho tirato fuori la versione definitiva che non dovrebbe dare problemi con nessuna versione del PHP.

    query=location.href.split("#")
    document.cookie='anchor='+query[1];
    if (query[1] != "phpTAG echo $a phpENDTAG") {
        window.location.reload()
    }

    isset* è importante perché su alcuni server, contententi php, è richiesta la dichiarazione delle variabili; in questo caso il cookie ‘anchor’ inizialmente non è dichiarato quindi potrebbe dare un errore di sintassi. Ho messo il codice PHP davanti allo script JS per caricare la variabile temporanea $a che assume il valore nullo, causando il reload della pagina, dopo di che, acquisisce il valore del cookie che si è formato.

  10. this worked for me, by using “window.location.hash”:

     
    	query=window.location.hash.split("#")
    	document.cookie='anchor='+query[1];
    	alert(query[1]);
    	if (query[1] != "") {
    		window.location.reload()
    	}
  11. @mycuztomlife – I have, but in this case it just doesn’t work. First of all parse_url() is a simple string manipulation function – if you give it a url it simply parses it and it will fill up an array with it’s components. But that is the case when you explicitely give the url from it. However when you work with javascript (something that happen entirely on the client side) you can change the #component part without refreshing the page. After all that changes PHP (cause it is on the server side) doesn’t understand what is in the url (especially the #component part). To do this you should send it to the server and explicitely give to parse_url() the url.

    Remember – parse_url doesn’t make requests or something that will take the url from your browser’s bar. It simply parses a string.

  12. Well using parse_url component, you can grab the fragremnt part
    parse_url($url, PHP_URL_FRAGMENT);

  13. Hi Stoimen !
    I know that is old topic but I need some help to make it working for my own case. I didn’t any contact link on your website.
    First of all, I don’t have any javascript knowledge but I could understand if you explain to me.

    here are my entire codes :
    testh.php :

    var query= window.location.href.split(‘#’);
    document.cookie= ‘now=’ + query[1];
    if (query[1] != “”) {
    window.location.reload()
    }

    HomeW.I.PGalleryAbout

    /*************** end testh.php *******************/
    body.php :

    Test

    Titre h2

    Titre h3

    Lorem ipsum dolor sit amet, consectetur adipiscing elit.

    Titre h3

    Lorem ipsum dolor sit amet, consectetur adipiscing elit.

    Titre h3

    Lorem ipsum dolor sit amet, consectetur adipiscing elit.

    Thanks for your help

  14. Hi Stoimen,

    how may I join you. I tried to post my code here to get some help beacause it doesn’t work for me but the message got moderated.

  15. I feel there is a small typo in the code (love the post though!) underneath you will find the correct code:

    query=location.href.split(‘#’)
    document.cookie= ‘anchor’ + query[1];

    No need for a = after anchor. You will magically notice the page won’t have to be reloaded .

  16. I think it can be improved. The way it is set up, in some cases, will return the full url or won’t load at once. So why not set it up like this to prevent a little trouble in paradise?

    query=location.hash;
    document.cookie= ‘anchor=’+query;

    and in php you can get the value you need by exploding that puppy:

    $split = explode(‘/’, $_COOKIE[‘anchor’]);
    print_r($split); //use print_r to test it in your screen
    print_r($split[1]); //get a value out of the array

    print_r is just for testing purposes of course.

Leave a Reply

Your email address will not be published. Required fields are marked *