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.