Read The Anchor Part of The URL … with PHP

submit to reddit

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.

Related posts:

  1. How to Overcome Zend_Cache_Frontend_Page’s Problem with Cookies
  2. javascript: detect browser speed and load the “slow connection” site version
  3. PHP: Fetch $_GET as String with http_build_query()

You are a GREAT developer? Click here to answer the weekly quiz!

This entry was posted in javascript, micro tutorial, PHP, web development and tagged , , , , , . Bookmark the permalink.

19 Responses to Read The Anchor Part of The URL … with PHP

  1. stoimen says:

    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. поздравления says:

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

  3. Mark says:

    Nice script! But I have a question, is it poissible to set a background-color when a anchor is active?

  4. Stoimen says:

    Sure you can! Please provide some sample code and I’ll try to help!

  5. nik says:

    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!

  6. Stoimen says:

    Please provide me some sample code you’d like to make work, or write me on popov AT stoimen DOT com

  7. Weblap.ro says:

    This is a quite good trick ;) That was I searching! Thanks!

  8. 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.

  9. 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>
  10. Luis Aveiga says:

    Interesting article… Didn’t know that PHP can’t read the # part.
    BTW, your blog design is great :)

  11. Boston says:

    Awesome article. Will come again. :-)

  12. MJ says:

    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?

  13. Summer says:

    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.

  14. Griffith says:

    i think using parse_url() native php method is simple enough.
    http://php.net/manual/en/function.parse-url.php

  15. Gene says:

    @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.

  16. Akanksha Jaidev says:

    rastronomicals : Thanks You code worked in one go… amazing

  17. Taras says:

    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.

  18. jihchuan says:

    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()
    	}
  19. whyte624 says:

    Very useful!
    Thanx!

Leave a Reply

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

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">