グローバル変数へのアクセスを回避する現在のユーザーオブジェクトを取得する関数はありますか?


29

私はいつもこれを使ってきましたglobal $user;。ただし、globalを使用せずに現在のユーザーオブジェクトを返す投稿モジュールで何かを見たことを覚えているようです$user

そのような関数はDrupal 7コアに存在しますか、それともグローバル変数を使用して、現在のユーザーオブジェクトを取得するための事実上の推奨方法ですか?


グローバル$ userを使用しないのはなぜですか?
saadlulu

5
グローバル$ userを使用すると、コードの後半で不注意に変更された場合に、望ましくない動作が発生する可能性があります。
アレックスウェーバー

回答:


22

使用できる関数はuser_uid_optional_load()です。引数なしで、現在ログインしているユーザーのユーザーオブジェクトを返します。それでもglobalを使用し、$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;
}

簡単な答えは、両方とも有効であるということです。の使用$GLOBALSは、指定された変数$userが現在のスコープでアクティブではなく、したがって、たとえば$user = NULL関数でさらに不注意に呼び出されても上書きできないようにするためだと思います。私はそれでも100%ではありません。


それがあなたの最後の声明で私が知って同意していることです。
saadlulu

1
global $user;通常、変数が複数回参照$GLOBALS['user']される場合に使用する必要があり、関数コードで1回のみ使用する場合に使用する必要があります。Drupalコードはその中で一定ではありません。global $user;必要な場合があります:drupal_alter()サードパーティのモジュールが現在アクティブなユーザー(Drupalで実際に実装されているものではない)を変更できるようにするためにユーザーオブジェクトが渡されるとき。
キアムルノ

1
global $useruser_uid_optional_load()と同じものではありません。1つ目はセッションからロードされ、2つ目は完全にロードされたユーザーオブジェクトではありません(フィールドとフックが呼び出されます)。したがって、これをオプションとしてリストしません。その関数の目的は、オプションでユーザーIDを受け入れることができる名前付きメニュー引数に使用されることであり、そうでなければデフォルトで現在のユーザーになります。/ user / uidが主な例です。
ベルディール

@Berdirありがとうglobal $userデフォルトでは完全にロードされていないことを知りませんでした(それは理にかなっており、以前考えていたいくつかのことを説明していますが)。私は答えからそれを取りました。
クライブ

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.