130

How can i select the fragment after the '#' symbol in my URL using PHP?
The result that i want is "photo45".

This is an example URL:
http://example.com/site/gallery/1#photo45

ilija veselica
  • 9,414
  • 39
  • 93
  • 147
  • 1
    @ile http://en.wikipedia.org/wiki/Hash_symbol – Pekka Feb 23 '10 at 11:20
  • 2
    Duplicate or at least on the same lines as http://stackoverflow.com/questions/1957030/retrieve-the-hash-in-the-url-with-php, http://stackoverflow.com/questions/1162008/php-hash-fragment-portion-of-url and http://stackoverflow.com/questions/2181290/php-zend-framework-how-to-get-request-uri-fragment-from-request-object – Gordon Feb 23 '10 at 12:09
  • 2
    possible duplicate of [How to get the value after the hash in "somepage.php#name"?](http://stackoverflow.com/questions/1917762/how-to-get-the-value-after-the-hash-in-somepage-phpname) – PhoneixS Jul 08 '15 at 09:39
  • 1
    PHP cannot obtain a complete URL, including the anchor name. Since anything JavaScript and the DOM can manipulate might need to be processed by PHP, it doesn't make sense that PHP cannot obtain the entire URL with which it is called. Seems to be a very big bug in PHP, unless I'm missing something. – David Spector Jan 02 '20 at 17:09
  • @DavidSpector You talk about a bug in PHP about a concept that is purely client-side: the anchor. – risingballs Jun 20 '21 at 19:06
  • Yes. The concept that it is okay to standardize on a mish-mash of three quirky languages that cannot completely communicate with each other on a single computer deserves critical examination, along with the related question of the security of the entire Web. Acceptance of that which exists is fine so long as what exists cannot be improved upon. Those of us with ideas for improvement have no forum in which to discuss them. – David Spector Jun 21 '21 at 10:24

10 Answers10

147

If you want to get the value after the hash mark or anchor as shown in a user's browser: This isn't possible with "standard" HTTP as this value is never sent to the server (hence it won't be available in $_SERVER["REQUEST_URI"] or similar predefined variables). You would need some sort of JavaScript magic on the client side, e.g. to include this value as a POST parameter.

If it's only about parsing a known URL from whatever source, the answer by mck89 is perfectly fine though.

Community
  • 1
  • 1
sfussenegger
  • 35,575
  • 15
  • 95
  • 119
52

That part is called "fragment" and you can get it in this way:

$url = parse_url("http://example.com/site/gallery/1#photo45 ");
echo $url["fragment"]; //This variable contains the fragment
roapp
  • 530
  • 6
  • 17
mck89
  • 18,918
  • 16
  • 89
  • 106
  • That is very good but it would have been without any error if you were to add ``` $fragment = isset($url['fragment']) ? '#' . $url['fragment'] : ''; ``` But still Thumbs Up !! – John Max Dec 19 '16 at 15:45
  • 20
    this works for a url saved inside a string not the actual url from the browser address bar – Muhammad Omer Aslam Apr 20 '18 at 21:37
  • 2
    This is true but not the correct answer for original question. The asker doesn't have the full URL string. – Derek Joseph Olson Oct 02 '18 at 23:22
  • 2
    The asker didn't specificallt say he hadn't the URL to be honest or that he needed the fragment from the URL currently displayed in the address bar of the browser. He asked how to parse the fragement from _an_ URL, so unless he edited his question, this answer should fine enough. – DrLightman Nov 05 '18 at 15:17
  • 3
    Actually you can get the fragment in one line: `$fragment = parse_url("http://example.com/site/gallery/1#photo45", PHP_URL_FRAGMENT);` – pstryk Mar 06 '19 at 23:32
48

A) already have url with #hash in PHP? Easy! Just parse it out !

if( strpos( $url, "#" ) === false ) echo "NO HASH !";
   else echo "HASH IS: #".explode( "#", $url )[1]; // arrays are indexed from 0

Or in "old" PHP you must pre-store the exploded to access the array:

$exploded_url = explode( "#", $url ); $exploded_url[1]; 

B) You want to get a #hash by sending a form to PHP?
    => Use some JavaScript MAGIC! (To pre-process the form)

var forms = document.getElementsByTagName('form'); //get all forms on the site
for (var i = 0; i < forms.length; i++) { //to each form...
    forms[i].addEventListener( // add a "listener"
        'submit', // for an on-submit "event"
        function () { //add a submit pre-processing function:
            var input_name = "fragment"; // name form will use to send the fragment
            // Try search whether we already done this or not
            // in current form, find every <input ... name="fragment" ...>
            var hiddens = form.querySelectorAll('[name="' + input_name + '"]');
            if (hiddens.length < 1) { // if not there yet
                //create an extra input element
                var hidden = document.createElement("input");
                //set it to hidden so it doesn't break view 
                hidden.setAttribute('type', 'hidden');
                //set a name to get by it in PHP
                hidden.setAttribute('name', input_name);
                this.appendChild(hidden); //append it to the current form
            } else {
                var hidden = hiddens[0]; // use an existing one if already there
            }

            //set a value of #HASH - EVERY TIME, so we get the MOST RECENT #hash :)
            hidden.setAttribute('value', window.location.hash);
        }
    );
}

Depending on your form's method attribute you get this hash in PHP by:
$_GET['fragment'] or $_POST['fragment']

Possible returns: 1. ""[empty string] (no hash) 2. whole hash INCLUDING the #[hash] sign (because we've used the window.location.hash in JavaScript which just works that way :) )

C) You want to get the #hash in PHP JUST from requested URL?

                                    YOU CAN'T !

...(not while considering regular HTTP requests)...

...Hope this helped :)

jave.web
  • 13,880
  • 12
  • 91
  • 125
9

I've been searching for a workaround for this for a bit - and the only thing I have found is to use URL rewrites to read the "anchor". I found in the apache docs here http://httpd.apache.org/docs/2.2/rewrite/advanced.html the following...

By default, redirecting to an HTML anchor doesn't work, because mod_rewrite escapes the # character, turning it into %23. This, in turn, breaks the redirection.

Solution: Use the [NE] flag on the RewriteRule. NE stands for No Escape.

Discussion: This technique will of course also work with other special characters that mod_rewrite, by default, URL-encodes.

It may have other caveats and what not ... but I think that at least doing something with the # on the server is possible.

Bronson
  • 91
  • 1
  • 4
7

You can't get the text after the hash mark. It is not sent to the server in a request.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
5

I found this trick if you insist want the value with PHP. split the anchor (#) value and get it with JavaScript, then store as cookie, after that get the cookie value with PHP

Machavity
  • 30,841
  • 27
  • 92
  • 100
jihchuan
  • 307
  • 1
  • 5
  • 14
2

If you are wanting to dynamically grab the hash from URL, this should work:

https://stackoverflow.com/a/57368072/2062851

<script>
    var hash = window.location.hash, //get the hash from url
    cleanhash = hash.replace("#", ""); //remove the #
    //alert(cleanhash);
</script>
<?php
    $hash = "<script>document.writeln(cleanhash);</script>";
    echo $hash;
?>
roapp
  • 530
  • 6
  • 17
samjco-com
  • 365
  • 5
  • 14
0

You can do it by a combination of javascript and php:

<div id="cont"></div>

And by the other side;

<script>
var h = window.location.hash;
var h1 = (win.substr(1));//string with no #
var q1 = '<input type="text" id="hash" name="hash" value="'+h1+'">';

setInterval(function(){
if(win1!="")
{
document.querySelector('#cont').innerHTML = q1;
} else alert("Something went wrong")
},1000);
</script>

Then, on form submit you can retrieve the value via $_POST['hash'] (set the form)

-2

You need to parse the url first, so it goes like this:

$url = "https://www.example.com/profile#picture";
$fragment = parse_url($url,PHP_URL_FRAGMENT); //this variable holds the value - 'picture'

If you need to parse the actual url of the current browser, you need to request to call the server.

$url = $_SERVER["REQUEST_URI"];
$fragment = parse_url($url,PHP_URL_FRAGMENT); //this variable holds the value - 'picture'
JJ Labajo
  • 296
  • 1
  • 16
  • 8
    On my server with apache 2.4.35 / PHP 7.0.26 the variable `$_SERVER['REQUEST_URI']` does **not** include the #fragment – user9645 Jan 09 '19 at 14:06
-5

Getting the data after the hashmark in a query string is simple. Here is an example used for when a client accesses a glossary of terms from a book. It takes the name anchor delivered (#tesla), and delivers the client to that term and highlights the term and its description in blue so its easy to see.

  1. setup your strings with a div id, so the name anchor goes where its supposed to and the JavaScript can change the text colors

    <div id="tesla">Tesla</div>
    <div id="tesla1">An energy company</div>
    
  2. Use JavaScript to do the heavy work, on the server side, inserted in your PHP page, or wherever..

    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    
  3. I am launching the Java function automatically when the page is loaded.

    <script>
    $( document ).ready(function() {
    
  4. get the anchor (#tesla) from the URL received by the server

    var myhash1 = $(location).attr('hash'); //myhash1 == #tesla
    
  5. trim the hash sign off of it

    myhash1 = myhash1.substr(1)  //myhash1 == tesla
    
  6. I need to highlight the term and the description so I create a new var

    var myhash2 = '1';
    myhash2 = myhash1.concat(myhash2); //myhash2 == tesla1
    
  7. Now I can manipulate the text color for the term and description

    var elem = document.getElementById(myhash1);
    elem.style.color = 'blue';
    elem = document.getElementById(myhash2);
    elem.style.color = 'blue';
    });
    </script>
    
  8. This works. client clicks link on client side (example.com#tesla) and goes right to the term. the term and the description are highlighted in blue by JavaScript for quick reading .. all other entries left in black..

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
James Danforth
  • 781
  • 7
  • 7