プログラムで現在のノードのNIDを取得する方法


26

私はdrupal.orgのこの古いスレッドに目を通しましたが、それはちょっと頭を動かすだけです。パスをプルダウンして、その中からNIDを解析しようとしていますか?より良い方法が必要です。

などのソリューション

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

カスタムモジュールでは動作しません(テンプレートで動作すると言われていますが)。エラーも何もありません。値でインスタンス化さ$nodeNULLます。

私が行方不明になっていることは本当に明白な何かがあるに違いないと感じています。

それでは、ベストプラクティスに従い、適度に堅牢なモジュールを構築しながら、テンプレートなしで現在のノードのNIDをどのように取得しますか?

回答:


50

ノードページでコードが実行されていると仮定すると、コア/ contribモジュールで最も頻繁に使用される方法は、menu_get_object()またはのいずれかを使用していますarg()

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

または

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
@Letharionうん、やるたびに少し罪悪感を覚える;)
クライブ

1
@bethどの関数から呼び出していますか?そして、それは間違いなくあなたがそれを呼び出しているノードページですか?
クライブ

1
@bethこれらは、パスエイリアシングを有効にすると100%動作します。パスエイリアシングは、メニュー項目のルーターパスとは関係ありませんnode/1node/2など)。まだ問題がある場合は、使用している正確なコードで別の質問を投稿する価値があり、コンテキストを少し提供する必要があります。その後、問題の発生場所を特定できる可能性があります
クライブ

1
一行ソリューション$nid = ($node = menu_get_object()) ? $node->nid : NULL;
timofey.com

3
@sheldonkregerノードはその時点ですでにロードされているmenu_get_object()(またはnode_load())だけで静的キャッシュから取得しています。あなたは上で早期にそれを呼び出す場合でも、まだ(これはノードのページのように)後にページのビルドでコアモジュールによってロードされることになるだろう、その場合にはあなただけの次のプロセスのための静的なキャッシュを温めることだろう
クライヴ

5

arg()が機能しなくなったため、Drupal 8でこれを行う最も簡単な方法:

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

レコードを変更する


2
これはDrupal 7でも機能します。ただし、admin / structure / blocksなどのノードではないページを使用している場合、無効な値(この場合は 'structure')を受け取ります。path_args [1]が整数であり、おそらく大丈夫かどうかを確認してください。
シェルドンクレガー14

それはすでにあなたのためのことを行っているので、あなたはおそらく、引数(1)を使用する代わりに爆発する:api.drupal.org/api/drupal/includes%21bootstrap.inc/function/arg/...を
RobLoach

1
@RobLoachがarg()はD8に存在しません
Pouya Sanooei


1

このリンクは私を助けました:http : //www.webomelette.com/node-id-nid-url-path-alias-コンテンツに移動し、downtをフィルターして、ノードIDを表示したいコンテンツを見つけ、編集の上にカーソルを置きますリンク。[編集]をクリックすると、ブラウザが従うことを通知するハイパーリンクが表示されます。


こんにちはAna、Drupal Answersへようこそ。あなたの答えは良いです(そして、私はその試みに賛成票を投じました)、しかし、質問はタイトルに「モジュールから」を含むので、プログラムでnidを得る方法を尋ねています。
ダルヴァネン14年

1

現在受け入れられている回答の2番目の方法は、D7で最もクリーンな方法です。最初の答え:

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

視覚的にのみきれいです。実際、menu_get_object()かなり多くのコードを呼び出しているため、予期しないエラーが発生する可能性があります。hook_node_grants()関数内で使用していて、PHPの致命的エラーに遭遇しました。

関数のネストレベルが最大「256」に達し、中止されました!

/drupal//a/69232/9158にある説明

あなたが気づかされ、無限ループが事実から生じて menu_get_object()Drupalは、現在ログインしているユーザーを確認するために、原因の実装原因となるノードへのアクセスがある hook_node_grants()の呼び出し再び呼び出されると、menu_get_object()あなたの実装が原因となる、hook_node_grants()再び呼び出されると、...

これは、2番目の方法を使用して解決されました。

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

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;
  }
}

モジュールの外部で関数を使用する場合は、関数名の先頭に先頭の_を使用しないでください。


1
これは同じことですが、ノードではないすべてのパスで高価なウォッチドッグコールを使用します。
ベス14

私のコードが予期せず失敗するかどうかを知りたいです。このコードが非ノードで実行されることは望ましくありません。ウォッチドッグは、それを修正できるように、それが発生している場所を表示します。それ以外の場合、このコードが理由もなく(非ノードで)実行されているというトレースはありません。それ以外の場合は、上記のD8メソッドと同じです。
シェルドンクレガー14

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

答えに「理由」と「方法」をいくつか追加してもらえますか?コードのみの答えは機能するかもしれませんが、間違いを理解するのはほとんど役に立ちません。
モウォ

実行前にノードが定義されているかどうかを最初にチェックします。
cptstarling
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.