Drupal - How do I get the node ID from the URL?

I am not really sure what the difference between them is

  • menu_get_object() returns the object associated with the page currently shown. If the code is executed when Drupal is showing the page example.com/node/1, then menu_get_object() will return the node object for the node whose ID is 1; if the page being shown is example.com/user/1, then menu_get_object('user') will return the user object for the user whose ID is 1.
  • menu_get_item() returns an array containing an index for each field contained in the "menu_router" table. This includes:
    • path: the current path of the menu callback
    • load_functions: an array of function names (like node_load) to be called to load an object corresponding to a part of the current path
    • access_callback: the callback that checks if the currently logged in user has access to the menu item
    • page_callback: the name of the function that renders the page
    • title: the title for the page associated to the menu item
  • drupal_lookup_path() is the function that returns you the internal path associated with the alias passed as argument. If "homepage" is the alias associated to example.com/node/1, then drupal_lookup_path("homepage") will return "node/1". Path aliases can be associated to any internal paths, not only to node paths.

and which is more appropriated to get the node ID in a block preprocess function.

If all you want to get is the node ID of the node currently shown, then you just need to use the following code:

if (arg(0) == 'node') {
  $nid = arg(1);

If you need to get the node object, then you can use the following code:

if ($node = menu_get_object()) {
  // Use the node object.

Of those snippets, the second is better, as it returns the correct node object for internal paths such as node/1/revisions/3/view.

Keep in mind that some preprocess functions, such as the ones for the page, or the node, have already a $variables['node']. This means that in those cases, you just need to use the following snippet in your preprocess function, without worrying about which function to use.

if (isset($variables['node'])) {
  // Check the node ID or other properties.

For other preprocess functions, check the documentation to see if there is any variable containing the node object. For example, that is the case for template_preprocess_comment() which makes $variables['node'] available to the preprocess functions for comments.

How it's done in Drupal Core's template_preprocess_page:

Line 2267 of theme.inc and onwards:

if ($node = menu_get_object()) {
    $variables['node'] = $node;

template_preprocess_page uses menu_get_object. After that it's just a matter of checking if the node is defined and getting $node->nid.

One thing you have to be careful of is path alias.


to get the current path use the system variable $_SERVER["REQUEST_URI"]

(If you are on the node page you can call $node->uri['path'], this will return a non-alias path. Then again if you are on the node page, you can just use $node->nid.)

this will return node/XXXX

so try something like

  $node_path = explode('/', drupal_get_normal_path($path));
  $nid = $node_path[1];