Amelia Earhart
Amelia Earhart

Reputation: 87

Change href based on URI using PHP

I'm trying to make a main menu bar link dynamic, based on the visitor's current page.

I started with

 $path = $_SERVER['REQUEST_URI'];

Which, of course, returns things like

I need to grab whatever is after the first '/'. I've tried messing around with explode, but I stumble with what to do with the resulting array. I'm also going cross-eyed trying to write a regex - seems a more elegant solution.

Then I need to build my switch. Something along the lines of:

switch ($path)
{
case '/subfolder0':
  $link = $root_url.'/subfolder0/anotherfolder/page.html';
  break;
case '/subfolder1':
  $link = $root_url.'/subfolder1/page.html';
  break;
default:
  $link = $root_url.'/subfolder2/page.html';
}

Finally, should I be using if...elseif for this in lieu of switch?

Thanks for your time, all!

Upvotes: 3

Views: 347

Answers (4)

anubhava
anubhava

Reputation: 785246

You can just use dirname function to get what you want:

$path = dirname('/subfolder/page.html'); // returns '/subfolder'
$path = dirname('/subfolder1/subfolder2/page.html'); // returns '/subfolder1'
$path = dirname('page.html'); // returns '.'

EDIT: Regex based solution:

$path = preg_replace('#^(/[^/]*).*$#', '$1', '/subfolder/page.html' )

Upvotes: 1

Andrew Senner
Andrew Senner

Reputation: 2509

After analyzing the OP's question, I think he/she meant to phrase it as "Everything after the first '/', but before the second '/'. Here is what I got:

You could try this regex:

<?php

/*
 *  Regex: /((\w+?|\w+\.\w+?)(?!^\/))(?=\/.*$|$)/
 */

$paths = array(
    '/subfolder9/',
    '/subfolder/page.html',
    '/subfolder1/subfolder2/page.html',
    '/page.html'
);

foreach ($paths as $path) {
    preg_match("/((\w+?|\w+\.\w+?)(?!^\/))(?=\/.*$|$)/", $path, $matches);
    debug($matches);
}

// $matches[1] will contain the first group ( ) matched in the expression.
// or "subfolder<#>" or "<page>.<ext>"

// The loop results is as follows:
Array
(
    [0] => subfolder9
    [1] => subfolder9
    [2] => subfolder9
)

Array
(
    [0] => subfolder
    [1] => subfolder
    [2] => subfolder
)

Array
(
    [0] => subfolder1
    [1] => subfolder1
    [2] => subfolder1
)

Array
(
    [0] => page.html
    [1] => page.html
    [2] => page.html
)

?>

Note: This only works with regex flavors that support look-arounds (zero-width positive & negative look ahead are the ones used the example.)

This a great cheat sheet for regular expressions and I don't code without it.

Regular-Expressions.info - (click to view)

Upvotes: 1

Ben Barkay
Ben Barkay

Reputation: 5622

Using explode is not at all a bad idea if you are interested in all the parts of the URI, you should take a look at the documentation for explode

Its usage would be like so:

$exploded = explode('/','/path/to/page.html');

echo $exploded[0]; // Will print out '' (empty string)
echo $exploded[1]; // Will print out 'path'
echo $exploded[2]; // Will print out 'to'
echo $exploded[3]; // Will print out 'page.html'

However as far as I understand, you are looking to replace the link by whatever is after the first character (which is always '/'), you could use substr like so:

// Get whatever is after the first character and put it into $path
$path = substr($_SERVER['REQUEST_URI'], 1); 

In your case, it is not needed because you are able to predict there is a backslash at the beginning of the string.

I would also suggest using an associative array to replace the URL.

I would implement the entire thing like so (removing the first backslash as you require):

// Define the URLs for replacement
$urls = array(
    'subfolder0' => '/subfolder0/anotherfolder/page.html',
    'subfolder1' => '/subfolder1/page.html'
);

// Get the request URI, trimming its first character (always '/')
$path = substr($_SERVER['REQUEST_URI'], 1);

// Set the link according to $urls associative array, or set
// the default URL if not found
$link = $urls[$path] or '/subfolder2/page.html';

Or with explode, taking only the first part of the URI:

// Get the parts of the request
$requestParts = explode('/', $_SERVER['REQUEST_URI']);

// Set the link according to $urls associative array, or set
// the default URL if not found
$link = $urls[$requestParts[1]] or '/subfolder2/page.html';

Upvotes: 1

Adrian
Adrian

Reputation: 46452

To grab everything after the first /:

strstr($_SERVER['REQUEST_URI'], '/');

Or, with regex:

preg_match('#(/.*)#', $_SERVER['REQUEST_URI'], $matches);  // $matches[1] will be the path

As far as the switch, I'd say if/elseif/else is the least-elegant in your case, switch isn't bad, but personally I'd go with an associative array:

$mapping = array('/subfolder0' => $root_url.'/subfolder0/anotherfolder/page.html', 'etc' => 'etc');
$link = $mapping($path);

This lets you keep the mapping in another file for organization, and makes it a little bit easier to maintain by separating configuration from implementation.

Upvotes: 2

Related Questions