Revealing Assumed Names - Drupal Paths and Aliases

The standard Drupal path is often ugly. Enter the path module, which lets us assign a friendlier alias path. Both the alias and the "real" path, typically called the Drupal path or the internal path, can be used to access the page. Internally Drupal always uses the Drupal path, regardless of which path was used for the original access. For example, if you assign the alias /about to /node/3, it's still /node/3 to Drupal.

The arg function gives us the Drupal path of the current page as component bits. For /node/3, the arg function returns arg(0) = node and arg(1) = 3. Even if the page is accessed via /about, the arg function returns arg(0) = node and arg(1) = 3. To get the Drupal path as a string, you can use $_GET['q'], which would return the string /node/3.

If you need the path the user actually entered things become a bit trickier. The global variable $_SERVER['REQUEST_URI'] seems like a good choice, but it's server specific: You may or may not find any of the following elements in $_SERVER. Note that few, if any, of these will be available (or indeed have any meaning) if running PHP on the command line.1

Fortunately, there's the Drupal request_uri function: Since $_SERVER['REQUEST_URI'] is only available on Apache, we generate an equivalent using other environment variables. 2

Continuing with our example, if the page is accessed with /about then $_GET['q'] = /node/3 and request_uri() = /about.

The examples so far have assumed Clean URLs are enabled. The arg function and $_GET['q'] global variable have the same values regardless of the Clean URL setting. The request_uri function does not. With Clean URLs disabled the request_uri function returns the path with "/?q=" prepended. In our example above, request_uri() would return /?q=about.

In all cases please, please, please remember that all these functions and global variables return UN-SANITIZED values. You open your code up to cross site scripting if you output these values without properly cleaning them up. Check out Handle text in a secure fashion in the Drupal handbook for information on sanitizing user input for the purposes of outputting it.

Here's some code you can place in page.tpl.php or in node body text (with the PHP input format selected) for observing the two paths in action.

<?php
 $index
= 0;
 
$arglist = array();
 while ((
$argvalue = arg($index)) != '') {
 
$arglist[] = 'arg' . $index . ': ' . $argvalue . '   ';
 
$index++;
 }
 print
'<div><strong>args():</strong> ' . check_plain(implode(' | ', $arglist)) . '</div>';
 print
'<div><strong>$_GET[\'q\']:</strong> ' . check_plain($_GET['q']) . '</div>';
 print
'<div><strong>request_uri():</strong> ' . check_plain(request_uri()). '</div>';
?>

Two other functions of possible interest:
drupal_get_path_alias: Given an internal Drupal path, return the alias set by the administrator.
drupal_get_normal_path: Given a path alias, return the internal path it represents.

[1]: PHP Manual: Predefined Variables
[2]: api.drupal.org: request_uri

Comments

Try that.

$_REQUEST['q'] works only in nonadmin mode