Como obter programaticamente o NID do nó atual


26

Eu examinei esse tópico antigo no drupal.org e isso meio que faz minha cabeça girar. Descendo o caminho e tentando analisar o NID de dentro dele? Tem que haver uma maneira melhor.

E soluções como

global $node;
$nid = $node->nid;

não funciona no meu módulo personalizado (embora me disseram que eles funcionam em modelos?). Sem erro ou qualquer coisa, apenas instancia $nodecom um NULLvalor.

Parece que deve haver algo realmente óbvio que estou perdendo.

Então, como você obtém o NID do nó atual sem um modelo, enquanto segue as práticas recomendadas e constrói um módulo razoavelmente robusto?

Respostas:


50

Supondo que seu código esteja sendo executado para uma página de nó, os métodos que eu vejo usados ​​com mais frequência nos módulos core / contrib estão usando menu_get_object()ou arg():

if ($node = menu_get_object()) {
  // Get the nid
  $nid = $node->nid;
}

ou

if (arg(0) == 'node' && is_numeric(arg(1))) {
  // Get the nid
  $nid = arg(1);

  // Load the node if you need to
  $node = node_load($nid);
}

Pessoalmente, prefiro o primeiro método (embora a atribuição em condições não seja considerada uma boa ideia por algumas pessoas), mas ambos são perfeitamente válidos.


11
@Letharion Sim, eu me sinto um pouco culpado toda vez que faço isso;)
— Clive

11
@ bet De que função você está chamando? E é definitivamente uma página de nó em que você está acessando?
— Clive

11
@beth Eles 100% funcionarão com o alias de caminho ativado. O alias de caminho não tem nada a ver com o caminho do roteador do item de menu node/1, node/2etc. Se você ainda estiver com problemas, pode valer a pena postar outra pergunta com o código exato que você está usando e fornecer um pouco de contexto. Talvez possamos identificar onde o problema está acontecendo
— Clive

11
Uma solução de linha única$nid = ($node = menu_get_object()) ? $node->nid : NULL;
— timofey.com

3
@sheldonkreger O nó já está carregado nesse ponto menu_get_object()(ou mesmo node_load()) está apenas obtendo-o do cache estático. Mesmo se você chamá-lo desde o início, ele ainda será carregado por um módulo principal posteriormente na compilação da página (como essa é uma página de nó); nesse caso, você estaria apenas aquecendo o cache estático para o próximo processo
— Clive

5

A maneira mais fácil de fazer isso no Drupal 8, pois arg () não funciona mais:

$path_args = explode('/', current_path());
print $path_args[1];

Alterar registro


2
Isso também funciona no Drupal 7. No entanto, se você estiver em uma página que não seja um nó, como admin / structure / blocks, receberá um valor inválido (neste caso, 'structure'). Simplesmente verifique se path_args [1] é um número inteiro e você provavelmente está bem.
— sheldonkreger

Você provavelmente desejará usar arg (1) em vez de explodir, já que isso já foi feito por você: api.drupal.org/api/drupal/includes%21bootstrap.inc/function/arg/…
— RobLoach

11
Não @RobLoach mas arg () não existe no D8
— Pouya Sanooei

4

arg(0)retorna 'nó' e arg(1)retorna o nó nid.

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

1

Esse link me ajudou: http://www.webomelette.com/node-id-nid-url-path-alias - Acesse Conteúdo e filtre downt para encontrar o conteúdo para o qual deseja ver o ID do nó e passe o mouse sobre o botão Editar ligação. Olhe para baixo para ver o hiperlink que seu navegador indica que ele seguirá se você clicar em Editar.


Olá Ana, bem-vindo ao Drupal Answers. Sua resposta é boa (e eu votei na tentativa), mas a questão é perguntar como obter o nid programaticamente, pois ele contém 'de um módulo' no título.
— Darvanen

1

O segundo método na resposta atualmente aceita é o mais limpo em D7. A primeira resposta:

if ($node = menu_get_object()) {
  // Get the nid
  $nid = $node->nid;
}

é apenas visualmente mais limpo. De fato, menu_get_object()está chamando bastante código e pode levar a erros imprevistos. Eu estava usando-o dentro de uma hook_node_grants()função e tive um erro fatal do PHP:

Nível máximo de aninhamento de funções de '256' atingido, abortando!

A explicação, encontrada em /drupal//a/69232/9158

O loop infinito que você está percebendo é causado pelo fato de fazer com que o menu_get_object()Drupal verifique se o usuário conectado no momento tem acesso ao nó, o que faz com que sua implementação hook_node_grants()seja chamada novamente, quais chamadas menu_get_object(), o que faz com que sua implementação hook_node_grants()seja chamada novamente , qual...

Isso foi resolvido usando o segundo método:

if (arg(0) == 'node' && is_numeric(arg(1))) {
  // Get the nid
  $nid = arg(1);

  // Load the node if you need to
  $node = node_load($nid);
}


-1

Outra opção, no D7:

function _my_module_get_nid() {
  $path_args = explode('/', current_path());
  //$nid = $path_args[1];
  if(is_int($path_args)) {
    return($path_args[1]);
  }
  // Log that we failed to load a NID.
  else {
    watchdog('my_module', 'Unable to gather NID at: ' . current_path(),  WATCHDOG_WARNING, NULL);
  return FALSE;
  }
}

Se você planeja usar a função fora do seu módulo, não use o _ inicial no início do nome da função.


11
É a mesma coisa, mas com uma chamada de vigilância cara em todos os caminhos que não são nós.
— beth

Eu gosto de saber se meu código está falhando inesperadamente. Eu não gostaria que esse código fosse executado em não-nós, o watchdog me mostrará onde isso está acontecendo, para que eu possa corrigi-lo. Caso contrário, não rastreamos que esse código esteja sendo executado sem motivo (em não-nós). Caso contrário, é o mesmo que o método D8 mencionado acima.
— sheldonkreger

-1
<?php
if (isset($node->nid) && count($node->nid) > 0){
  $mynodeid = $node->nid;
}
?>

Você poderia adicionar alguns "porquês" e "comos" à sua resposta? A resposta somente de código pode funcionar, mas dificilmente ajuda a entender os erros.
— Mołot 16/01

Ele primeiro verifica se o nó está definido antes da execução.
— Csstarling
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.