navigation menu class active with php basename($_SERVER["REQUEST_URI"]

4k Views Asked by At

I have looked through all the questions here, but can't find the answer to this question.

I am sure it is a simple answer.

I have navigation menu, which is a PHP file and is included on each page.

I add a class active (I actually call it class current) using the following:

<a class="menu-nav <?php if (basename($_SERVER["REQUEST_URI"]) == '/past-events/index.php') echo "current";?>" href="http://website.com.au/past-events">PAST EVENTS</a>

This works fine for all the other pages because they are in the root directory, (actually with the other pages I use basename($_SERVER["SCRIPT_NAME"] ) but with the above page, because it is in the 'past-events' directory, it is not working.

I have tried:

<a class="menu-nav <?php if (basename($_SERVER["REQUEST_URI"]) == '/past-events/') echo "current";?>" href="http://website.com.au/past-events">PAST EVENTS</a>

but to no avail.

I should mention that the code is in a file called nav.php that lives in a foldr called 'includes' and is brought into each file that needs it using a php include

Can anyone see what I am doing wrong here?

Cheers, Al

5

There are 5 best solutions below

1
On BEST ANSWER

Thank you all for your time and effort in trying to help me.

I ended up adding:

<?php print $_SERVER["REQUEST_URI"]; ?>

to the page /past-events/index.php and found that it printed '/past-events/'

so all I needed to do was get rid of the basename() and it worked fine:

<a class="menu-nav <?php if ($_SERVER["REQUEST_URI"] == "/past-events/") echo "current";?>" href="http://website.com/past-events">PAST EVENTS</a>

This will of course mean that all files in this directory will get class="current" but this suits my design just fine.

Again, thank you for taking the time to help me. Cheers, Al.

4
On

You can use explode() instead of basename().

The explode function documentation: https://www.php.net/manual/en/function.explode.php

An example:

// Remove the two consecutive slashes and everything preceding them.
$uri = preg_replace(/.*(\/\/)/, '', $SERVER["REQUEST_URI"]);

// Explode each part of the uri in its own array position.
$uri_parts = $explode('/', $uri);

// The count of how many parts you got back.
$uri_parts_count = count($uri_parts);

// The index before the last one is the containing folder.
$uri_folder = $uri_parts[$uri_parts_count-1];

// The last index is the file that was requested.
$uri_file = $uri_parts[$uri_parts_count];

Another option is to use __DIR__ or dirname(__FILE__) depending on the PHP version you are using. Either of those two ways will return the folder name where the file that is executed by PHP resides in.

The implementation is similar to the above, the only difference is that you are trying to figure out which file it is accessed, instead of which URI was requested (better practice and more secure).

I hope this clears it a bit for you.

6
On

i would suggest to go for a more general approach, try fetching the uri and then use explode

assuming your URL is www.abc.com/blah1/blah2/page.php

so $_SERVER["REQUEST_URI"] = "www.abc.com/blah1/blah2/page.php"

so, (understand this carefully)

you can explode, uri, on the basis of /, so all the url parts are available to you for compare in a generic format

$my_url = $_SERVER["REQUEST_URI"];
$url_pieces = explode("/", $my_url);
$len = count($url_pieces);


echo $url_pieces[0]; // it has `www.abc.com`
echo $url_pieces[1]; // it has `blah1`
.
.
.
echo $url_pieces[$len-1]; /* this has page name */

Now you want to compare the, just use the last part to compare!!!

so for index.php, you can write something like

if($url_pieces[$len-1] == "index.php") echo "current"

and for all other in past-events folder

if($url_pieces[$len-1] != "index.php" && $url_pieces[$len-2] == "past-events" ) echo "current"

EDIT

To get the completer url, you can use below code (without any tags stripped or without worrying about http/https protocol) :

$url = "http" . (($_SERVER['SERVER_PORT']==443) ? "s://" : "://") . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
1
On

try this it will work

$basename=substr(strtolower(basename($_SERVER['PHP_SELF'])),0,strlen(basename($_SERVER['PHP_SELF']))-4);

<a class="menu-nav  <?php if ($basename== 'index') echo "current"; ?>" 

href="http://website.com.au/index.php">home</a>
0
On

so basically just make the function into an variable and use him in the actual nav bar or wherever. include this at the top of your header.php file or call it from includes

$activePageClean = basename($_SERVER['PHP_SELF'], ".php");
$activePage = htmlspecialchars($activePageClean);

then in your nav menu go something like this:

<div class="collapse navbar-collapse justify-content-end" id="navbarSupportedContent">
    <ul class="navbar-nav justify-content-end">
      <li class="nav-item <?= ($activePage == 'index') ? 'active':''; ?>">
        <a class="nav-link" href="/">Home</a>
      </li>

etc. for more list items. works perfectly PHP 7+. Then if we want we can render more nav items base on sessions or whatever we choose. You get the idea though. just replace the $activePage == '?' to what you want to check for & if it results to true then it adds class active or whatever class name you choose

<?php if (isset($_SESSION['id'])) {
    echo ' <li class="nav-item '?><?= ($activePage == 'add-contact') ? 'active':''; ?><?php echo '">
    <a class="nav-link" href="/add-contact.php">Add Contacts</a>
  </li>
  <li class="nav-item '?><?= ($activePage == 'create-csv') ? 'active':''; ?><?php echo '">
  <a class="nav-link" href="/create-csv.php">Create CSV</a>
  </li>
  <li class="nav-item '?><?= ($activePage == 'search-database') ? 'active':''; ?><?php echo '">
  <a class="nav-link" href="/search-database.php">Search Database</a>
  </li> ';
   }
  ?>