전역 변수에 대한 액세스를 피하는 현재 사용자 객체를 가져 오는 기능이 있습니까?


29

나는 항상 이것과 함께 갔다 global $user;. 그러나 global을 사용하지 않고 현재 사용자 객체를 반환하는 기여 모듈에서 무언가를 본 것을 기억합니다 $user.

이러한 기능이 Drupal 7 코어에 존재합니까, 아니면 전역 변수를 사용하여 현재 사용자 객체를 얻는 데 실제로 권장되는 방법입니까?


왜 글로벌 $ user를 사용하지 않습니까?
saadlulu

5
전역 $ user를 사용하면 나중에 코드에서 부주의하게 변경되는 경우 원치 않는 동작이 발생할 수 있습니다.
Alex Weber

답변:


22

사용할 수있는 함수는 user_uid_optional_load ()입니다 . 인수가 없으면 현재 로그인 한 사용자의 사용자 개체를 반환합니다. 여전히 전역을 사용하고 $user사용자와 관련된 필드를 포함하여 데이터베이스에서 전체 객체를로드하지만 실수로 $user코드에서 참조하지 않으므로 코드가 실수로 전역 변수의 내용을 변경하지 않도록합니다 .

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

전체 객체가 필요하지 않으면 다른 답변에 이미보고 된 코드를 사용할 수 있습니다. 전역 객체를 변경하지 않으려면 다음 코드 조각과 같이 전역 변수를 로컬 변수에 복사 할 수 있습니다.

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

Drupal 8에서는 정적 메소드 \Drupal::currentUser()를 사용하여 Drupal 7 $GLOBALS['user']과 동등한 기능을 사용 \Drupal\user\Entity\User::load(\Drupal::currentUser()->id())하고 모든 필드 API 필드가있는 완전히로드 된 오브젝트를 가져옵니다. 더 이상 모든 결과로 전역 변수를 재정의 할 위험이 없습니다.
현재 사용자를 익명 사용자로 전환해야하는 경우 Drupal 8에서 사용하는 코드는 다음과 같습니다.

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

// Your code here.

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

20

$user객체는 당신이 중 하나를 사용할 필요가 액세스 할 그렇다면, 전역 변수로 선언된다 :

global $user;
$account = $user;

또는

$account = $GLOBALS['user'];

Drupal에서는 실제로 이것을 수행하는 표준 방법이 아닌 것 같습니다. 예를 들어 노드 모듈을 보면 node_access_grants()함수는 다음 코드를 사용합니다.

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

파일의 바로 다음 기능인이 기능을 node_access_view_all_nodes()사용합니다.

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

간단한 대답은 둘 다 유효하다는 것입니다. I는 사용 생각 $GLOBALS라는 변수가되는 그래서 $user, 현재 활성 범위가 아니므로, 예를 들어 부주의 호, 덮어 쓸 수없는 $user = NULL상기 함수에. 나는 그것에 100 %가 아닙니다.


그것이 당신의 마지막 진술에서 내가 알고 동의하는 것입니다.
saadlulu

1
global $user;변수가 두 번 이상 참조 될 때 일반적으로 사용 $GLOBALS['user']되어야하며 함수 코드에서 한 번만 사용될 때 사용해야합니다. 드루팔 코드는 그 점에서 일정하지 않습니다. global $user;필요한 경우 가 있습니다 : drupal_alter()타사 모듈이 현재 활성 사용자 (Drupal에서 실제로 구현 된 것이 아님)를 변경할 수 있도록 하기 위해 사용자 개체가 전달 될 때 .
kiamlaluno

1
global $useruser_uid_optional_load ()와 동일하지 않습니다. 첫 번째는 세션에서로드되고 두 번째는 전체로드 된 사용자 오브젝트 (필드 및 후크가 호출 된)가 아닙니다. 그래서 나는 이것을 옵션으로 나열하지 않을 것입니다. 해당 함수의 목적은 선택적으로 사용자 ID를 허용하고 그렇지 않으면 현재 사용자를 기본값으로 지정할 수있는 명명 된 메뉴 인수에 사용됩니다. / user / uid가 기본 예입니다.
Berdir

@ Berdir 고마워 나는 global $user기본적으로 완전히로드되지 않았다는 것을 몰랐다 . 나는 대답에서 그것을 꺼 냈습니다.
Clive

Clive에게 감사드립니다. 전 세계 $ user를 사용하여 $ account 변수에 복사하는 것이 가장 안전한 대안이라고 생각합니다. 나는 실제로 user_uid_optional_load ()를 찾았습니다 :)
Alex Weber

3

함수 범위 내에서 (기존) 전역 $ user 객체를 선언하는 것만 큼 간단합니다.

global $user;

이 객체의 변경 사항은 전 세계에 영향을 미칩니다.

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

현재 사용자에게 uid 1 권한을 부여했습니다. 그렇기 때문에 일반적으로 $ user가 $ account에 할당되어 현재 로그인 한 사용자에게 실제로 영향을 미치지 않고 데이터를 땜질 할 수 있습니다 (물론 원치 않는 한).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.