5

多くのLaravel 4は私にとって初めてなので、これがばかげた質問である場合はお詫びします。独自のパスワード検証ルール (投稿時にコアにハードコードされている) を定義し、エラー報告の方法を変更したいので、コア パスワード機能のいくつかのメソッドをオーバーライドしようとしています (で使用される $errors 配列セッションベースではなく、他の形式)。

したがって、私のアプローチは、 /app/lib/MyProject/User に Password.php という新しいクラスを作成することでした。これは次のようになります。

<?php namespace MyProject\User;

use Closure;
use Illuminate\Mail\Mailer;
use Illuminate\Routing\Redirector;
use Illuminate\Auth\UserProviderInterface;

    class Password extends \Illuminate\Support\Facades\Password
    {
        /**
     * Reset the password for the given token.
     *
     * @param  array    $credentials
     * @param  Closure  $callback
 * @return mixed
 */
public function reset(array $credentials, Closure $callback)
{
    // If the responses from the validate method is not a user instance, we will
    // assume that it is a redirect and simply return it from this method and
    // the user is properly redirected having an error message on the post.
    $user = $this->validateReset($credentials);

    if ( ! $user instanceof RemindableInterface)
    {
        return $user;
    }

    $pass = $this->getPassword();

    // Once we have called this callback, we will remove this token row from the
    // table and return the response from this callback so the user gets sent
    // to the destination given by the developers from the callback return.
    $response = call_user_func($callback, $user, $pass);

    $this->reminders->delete($this->getToken());

    return $response;
}

}

/vendor/laravel/framework/src/Illuminate/Auth/Reminders/PasswordBroker.php からリセット メソッドをコピーしました。これは、コアの Password ファサードが解決される場所のようです。

次に、composer.json ファイルで、autoload:classmap 配列に以下を追加しました。

"app/lib/MyProject/User"

最後に、/app/config/app.php ファイルで、パスワード エイリアスを修正しました。

'Password' => 'MyProject\User\Password',

わかった。私のroutes.phpファイルには、ドキュメントからほとんど直接取られた次のものがあります。

Route::post('password/reset/{token}', function()
{
    $credentials = array('email' => Input::get('email'));

    return Password::reset($credentials, function($user, $password)
    {
        $user->password = Hash::make($password);

        $user->save();

        return 'saved - login';
    });
});

この reset() メソッドを実行すると、次のエラーが発生します。

非静的メソッド MyProject\User\Password::reset() を静的に呼び出すべきではありません

私が拡張しているクラスの reset() メソッドは static ではないので驚きましたが、reset メソッドを static に設定すると、そのエラーがクリアされます。次に、次のエラーが表示されます。

オブジェクト コンテキスト以外で $this を使用する

$this->validateReset($credentials) を実行しようとすると発生します。

私は今、完全に私の深さから外れています。私はこれを正しい方法で行っていますか、それとも完全に正しい道から外れていますか?

アドバイスをありがとう

4

2 に答える 2

2

ここでの前の回答は一般的に正しいですが、何が起こっているのかを説明するには十分ではありません。

一般に、ファサード メソッドへのアクセスは静的に行われると言えば十分です。そのため、ファサードで (パブリック) メソッドを定義する場合は、それが静的メソッドであることを確認する必要があります。ただし、ファサードは実際には、基礎となる非静的クラスのファサードであり、魔法のメソッドを使用して、ファサードの静的呼び出しを基礎となるクラスのインスタンス メソッドに渡します。そのため、通常、静的メソッドを定義してファサードを拡張するのではなく、基礎となるクラスでインスタンス メソッドを定義します。Passwordファサードの場合、基礎となるクラスは のインスタンスですPasswordBroker。この基本クラスの dealio は、通常、IoC コンテナーにインスタンスを登録することによってセットアップされます。次に、ファサードでgetFacadeAccessor、インスタンスを見つけるための IoC キーを返すファサード クラスのメソッドを定義します。(の場合、Passwordファサード、IoC キーはauth.reminder.)

ただし、Laravelコアクラスをオーバーライドすることはできないため、ここで問題が発生します。最も正しい方法は、おそらく拡張PasswordBrokerしてから、Password ファサードが通常使用する IoC のキーとしてクラスのバージョンを設定することです ( auth.reminder)。そうすれば、追加されたメソッドはファサードで利用可能になりますが、それ以外は元のPasswordBrokerクラスに従います。


新しいファサードを作成する必要はなく、既存のファサードの IoC キーをオーバーライドするだけであることがわかります。これをいつ行うかは、少し難しい場合があります。独自のサービス プロバイダーを使用しておらず、このようroutes.phpなことを何かで行っている場合は、おそらく安全です。ただし、サービスプロバイダーを使用してこのパスワードの動作を変更している場合、Laravel がサービスプロバイダーのメソッドを呼び出す順序に実際に依存することはできません (すべきではありません) (実際にはregister、設定された順序で行われるように見えます)。でapp/config/app.php、しかしそれを無視してください。これは未定義の動作なので、それに依存しないでください)。registerそのため、サービス プロバイダーのメソッドが Laravel のコア認証サービス プロバイダーの前または後に呼び出されるかどうかはわかりません。

これを整理する正式な方法はわかりませんが、私が考える唯一の方法は、サービスプロバイダーのbootメソッドではなく、サービスプロバイダーのメソッドで登録を行うことregisterです。特定のメソッドが常に他のすべてのサービスプロバイダーのメソッドのboot後に呼び出されることを保証できるため、Laravel コアキーをオーバーライドすることになり、通常の Laravel セットアップによってキーがオーバーライドされることはありません。ただし、メソッドでそれを行うと、理論的には、拡張しようとしている機能が別のサービス プロバイダーのメソッドで呼び出される可能性がある場合、必要なことを行うには遅すぎる可能性があります。registerbootboot

または、独自のファサードを作成、独自に選択したキーを使用して、すべてを通常どおりに設定します (つまり、registerメソッドにインスタンスを登録します)。次に、Password のエイリアスをファサードに置き換えます。それはよりボイラープレートですが、より確実に動作します。

于 2014-03-26T14:22:22.190 に答える