Có một chức năng để có được đối tượng người dùng hiện tại mà tránh truy cập vào biến toàn cầu?


29

Tôi đã luôn luôn đi với điều này global $user;. Tuy nhiên, tôi dường như nhớ rằng đã thấy một cái gì đó trong một mô-đun đóng góp trả về đối tượng người dùng hiện tại mà không sử dụng toàn cầu $user.

Liệu một chức năng như vậy có tồn tại trong lõi Drupal 7 hay đang sử dụng biến toàn cục theo cách được đề xuất thực tế để có được đối tượng người dùng hiện tại?


Tại sao bạn không sử dụng người dùng $ toàn cầu?
saadlulu

5
Sử dụng toàn cầu $ user có thể tạo ra hành vi không mong muốn tiềm tàng nếu nó được thay đổi một cách bất cẩn sau này trong mã.
Alex Weber

Câu trả lời:


22

Hàm bạn có thể sử dụng là user_uid_optional_load () ; không có đối số, nó trả về đối tượng người dùng cho người dùng hiện đang đăng nhập. Nó vẫn sử dụng toàn cục $uservà tải toàn bộ đối tượng từ cơ sở dữ liệu, bao gồm các trường liên quan đến người dùng, nhưng nó tránh mã của bạn vô tình thay đổi nội dung của biến toàn cục $user, vì nó không được tham chiếu từ mã của bạn.

function user_uid_optional_load($uid = NULL) {
  if (!isset($uid)) {
    $uid = $GLOBALS['user']->uid;
  }
  return user_load($uid);
}

Nếu bạn không cần đối tượng đầy đủ, thì bạn có thể sử dụng mã đã được báo cáo trong các câu trả lời khác. Nếu bạn muốn chắc chắn rằng bạn không thay đổi đối tượng toàn cầu, bạn có thể sao chép biến toàn cục thành biến cục bộ, như trong đoạn trích sau.

$account = $GLOBALS['user'];
// Use $account.

Trong Drupal 8, bạn chỉ cần sử dụng phương thức tĩnh \Drupal::currentUser()để có được tương đương với Drupal 7 $GLOBALS['user']\Drupal\user\Entity\User::load(\Drupal::currentUser()->id())để có được một đối tượng được tải đầy đủ với tất cả các trường API trường của nó. Không còn nguy cơ ghi đè một biến toàn cầu với tất cả các hậu quả.
Trong trường hợp bạn cần chuyển đổi người dùng hiện tại, ví dụ: người dùng ẩn danh, mã bạn sử dụng trong Drupal 8 là mã sau đây.

$accountSwitcher = Drupal::service('account_switcher');
$accountSwitcher->switchTo(new Drupal\Core\Session\AnonymousUserSession());

// Your code here.

// Eventually, restore the user account.
$accountSwitcher->switchBack();

20

Đối $usertượng được khai báo là biến toàn cục, vì vậy nếu bạn muốn truy cập nó, bạn cần sử dụng một trong hai:

global $user;
$account = $user;

hoặc là

$account = $GLOBALS['user'];

Thực tế dường như không có một cách tiêu chuẩn để làm điều này trong Drupal. Nếu bạn nhìn vào mô-đun nút chẳng hạn, node_access_grants()hàm sẽ sử dụng mã này:

if (!isset($account)) {
  $account = $GLOBALS['user'];
}

Trong khi chức năng tiếp theo trong tệp node_access_view_all_nodes(), sử dụng điều này:

global $user;
if (!$account) {
  $account = $user;
}

Câu trả lời đơn giản là cả hai đều hợp lệ. Tôi nghĩ rằng việc sử dụng $GLOBALSlà để biến có tên $userkhông hoạt động trong phạm vi hiện tại và do đó không thể bị ghi đè bởi một cuộc gọi bất cẩn, ví dụ, $user = NULLthêm về chức năng. Tôi không 100% về điều đó mặc dù.


đó là những gì tôi biết và đồng ý trong tuyên bố cuối cùng của bạn.
saadlulu

1
global $user;nên thường được sử dụng khi biến được tham chiếu nhiều lần và $GLOBALS['user']nên được sử dụng khi nó chỉ được sử dụng một lần trong mã chức năng; Mã Drupal không phải là hằng số trong đó. Có một trường hợp global $user;cần thiết: khi đối tượng người dùng được chuyển qua để drupal_alter()cho phép các mô-đun của bên thứ ba thay đổi người dùng hiện đang hoạt động (đây không phải là điều thực sự được triển khai trong Drupal).
kiamlaluno

1
global $userkhông giống với user_uid_optional_load (). Cái đầu tiên được tải từ phiên và không phải là một đối tượng người dùng được tải đầy đủ (với các trường và hook được gọi) trong khi cái thứ hai là. Vì vậy, tôi sẽ không liệt kê đây là một lựa chọn. Mục đích của chức năng đó là được sử dụng cho các đối số menu được đặt tên có thể tùy ý chấp nhận id người dùng và mặc định cho người dùng hiện tại. / user / uid là ví dụ chính.
Berdir

@Berdir Cảm ơn tôi không biết global $usermặc định không được tải đầy đủ (mặc dù nó có ý nghĩa và giải thích một vài điều tôi đã tự hỏi về trước đây). Tôi đã đưa nó ra khỏi câu trả lời.
Clive

Cảm ơn Clive, tôi cho rằng sử dụng người dùng $ toàn cầu và sao chép nó vào biến tài khoản $ có lẽ là cách thay thế an toàn nhất. Tôi thực sự đã tìm kiếm user_uid_optional_load () :)
Alex Weber

3

Nó đơn giản như việc khai báo đối tượng người dùng $ toàn cầu (hiện có) trong phạm vi hàm của bạn:

global $user;

Hãy nhớ rằng những thay đổi được thực hiện cho đối tượng này ảnh hưởng đến nó trên toàn cầu, nghĩa là

global $user;
$user->uid = 1;

chỉ cung cấp cho người dùng hiện tại uid 1 đặc quyền. Đây là lý do tại sao thông thường $ user được gán cho tài khoản $ để dữ liệu có thể được sửa đổi mà không thực sự ảnh hưởng đến người dùng hiện đang đăng nhập (tất nhiên trừ khi bạn muốn).

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.