Làm thế nào để lập trình lấy NID của nút hiện tại


26

Tôi đã xem qua chủ đề cũ này trên drupal.org và nó chỉ khiến tôi quay cuồng. Kéo xuống con đường và cố gắng phân tích NID từ bên trong nó? Có phải là một cách tốt hơn.

Và giải pháp như

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

không hoạt động trong mô-đun tùy chỉnh của tôi (mặc dù tôi được bảo là chúng hoạt động trong các mẫu?). Không có lỗi hay bất cứ điều gì, nó chỉ khởi tạo $nodevới một NULLgiá trị.

Cảm giác như phải có một cái gì đó thực sự rõ ràng mà tôi đang thiếu.

Vì vậy, làm thế nào để bạn có được NID của nút hiện tại mà không có mẫu, trong khi thực hiện theo các thực tiễn tốt nhất và xây dựng một mô-đun hợp lý mạnh mẽ?

Câu trả lời:


50

Giả sử mã của bạn đang chạy cho một trang nút, các phương thức tôi thấy được sử dụng thường xuyên nhất trong các mô-đun lõi / đóng góp đang sử dụng menu_get_object()hoặc arg():

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

hoặc là

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

Cá nhân tôi thích phương pháp đầu tiên (mặc dù việc chuyển nhượng trong điều kiện không được coi là ý tưởng tốt của một số người), nhưng cả hai đều hoàn toàn hợp lệ.


1
@Letharion Vâng, tôi cảm thấy có chút tội lỗi mỗi khi tôi làm điều đó;)
Clive

1
@beth Bạn gọi nó từ chức năng gì? Và nó có chắc chắn là một trang nút bạn đang gọi nó không?
Clive

1
@beth Họ 100% sẽ hoạt động với tính năng khử răng cưa. Bí danh đường dẫn không liên quan gì đến đường dẫn bộ định tuyến của mục menu node/1, node/2v.v. Nếu bạn vẫn gặp sự cố, có thể đáng để đăng một câu hỏi khác với mã chính xác bạn đang sử dụng và cung cấp một chút ngữ cảnh. Sau đó, chúng tôi có thể xác định chính xác nơi xảy ra sự cố
Clive

1
Một giải pháp dòng đơn$nid = ($node = menu_get_object()) ? $node->nid : NULL;
timofey.com 5/12/13

3
@sheldonkreger Nút đã được tải bởi điểm đó, menu_get_object()(hoặc thậm chí node_load()) chỉ là lấy nó từ bộ đệm tĩnh. Ngay cả khi bạn gọi nó sớm, nó vẫn sẽ được tải bởi một mô-đun lõi sau này trong quá trình xây dựng trang (vì đây là trang nút), trong trường hợp đó, bạn chỉ cần làm ấm bộ đệm tĩnh cho quy trình tiếp theo
Clive

5

Cách dễ nhất để làm điều này trong Drupal 8 vì arg () không còn hoạt động:

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

Thay đổi hồ sơ


2
Điều này cũng hoạt động trong Drupal 7. Tuy nhiên, nếu bạn ở trên một trang không phải là nút, chẳng hạn như quản trị / cấu trúc / khối, thì bạn sẽ nhận được giá trị không hợp lệ (trong trường hợp này là 'cấu trúc'). Chỉ cần kiểm tra xem liệu path_args [1] có phải là số nguyên không và bạn có thể ổn.
sheldonkreger

Bạn có thể sẽ muốn sử dụng arg (1) thay vì phát nổ, vì nó đã làm điều đó cho bạn: api.drupal.org/api/drupal/includes%21bootstrap.inc/feft/arg/ tựa
RobLoach

1
@RobLoach nhưng arg () không tồn tại trong D8
Pouya Sanooei

4

arg(0)trả về 'nút' và arg(1)trả về nút nid.

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

1

Liên kết này đã giúp tôi: http://www.webomelette.com/node-id-nid-url-path-alias - Chuyển đến Nội dung và lọc bộ lọc để tìm nội dung bạn muốn xem ID Node và di chuột qua Chỉnh sửa liên kết. Nhìn xuống để thấy siêu liên kết mà trình duyệt của bạn cho bạn biết nó sẽ theo sau nếu bạn nhấp vào Chỉnh sửa.


Xin chào Ana, chào mừng đến với Câu trả lời của Drupal. Câu trả lời của bạn là tốt (và tôi đã bỏ phiếu cho nỗ lực này), tuy nhiên câu hỏi đặt ra là làm thế nào để có được nid theo chương trình vì nó chứa 'từ một mô-đun' trong tiêu đề.
Darvanen

1

Phương pháp thứ hai trong câu trả lời hiện được chấp nhận là sạch nhất trong D7. Câu trả lời đầu tiên:

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

chỉ sạch hơn về mặt thị giác. Trong thực tế, menu_get_object()việc gọi khá nhiều mã và có thể dẫn đến các lỗi không lường trước được. Tôi đã sử dụng nó bên trong một hook_node_grants()hàm và gặp phải lỗi nghiêm trọng về PHP:

Mức lồng tối đa của hàm '256' đạt được, hủy bỏ!

Lời giải thích, được tìm thấy tại /drupal//a/69232/9158

Vòng lặp vô hạn mà bạn nhận thấy là do thực tế menu_get_object()khiến Drupal xác minh người dùng đang đăng nhập hiện có quyền truy cập vào nút, khiến cho việc thực hiện của hook_node_grants()bạn được gọi lại, điều menu_get_object()đó khiến cho việc thực hiện của hook_node_grants()bạn được gọi lại , mà ...

Điều này đã được giải quyết bằng cách sử dụng phương pháp thứ hai:

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

Một tùy chọn khác, trong 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;
  }
}

Nếu bạn có kế hoạch sử dụng chức năng bên ngoài mô-đun của mình, không sử dụng _ hàng đầu khi bắt đầu tên của chức năng.


1
Đây là điều tương tự nhưng với một cuộc gọi theo dõi đắt tiền trên tất cả các đường dẫn không phải là nút.
beth

Tôi muốn biết nếu mã của tôi bị lỗi bất ngờ. Tôi không muốn mã này được thực thi trên các nút không, cơ quan giám sát sẽ chỉ cho tôi biết nơi đó đang xảy ra để tôi có thể sửa nó. Mặt khác, tôi sẽ không có dấu vết nào cho thấy mã này đang chạy mà không có lý do (trên các nút không). Mặt khác, nó giống như phương pháp D8 đã đề cập ở trên.
sheldonkreger

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

Bạn có thể vui lòng thêm một số "whys" và "hows" vào câu trả lời của mình không? Câu trả lời chỉ có mã có thể hoạt động, nhưng hầu như không giúp hiểu được sai lầm của một người.
Mołot

Đầu tiên nó kiểm tra nếu nút được xác định trước khi thực hiện.
cptstarling
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.