【问题标题】:How can I extend class Confide in Laravel 4?如何在 Laravel 4 中扩展 Confide 类?
【发布时间】:2013-12-11 21:22:44
【问题描述】:

我想扩展/覆盖logAttemptConfide (Confide on GitHub) 中的方法,以便在有人成功登录时执行一些额外的代码。这比将相同的代码复制到调用logAttempt 的所有控制器更干净。

我在 stackoverflow 上阅读了 Laravel 文档和几个答案,但我就是无法正常工作。

我创建了一个新文件夹 app/extensions,其中包含一个名为 Confide.php 的文件:

<?php

namespace Extensions;

class Confide extends \Zizaco\Confide\Confide {

    public function __construct(ConfideRepository $repo) {
        die('no way!');
        $this->repo = $repo;
        $this->app = app();
    }

    public function logAttempt($credentials, $confirmed_only = false, $identity_columns = array()) {
        die('yeah man!');
    }
}

我将目录添加到我的app/start/global.php

ClassLoader::addDirectories(array(
    // ...
    app_path().'/extensions',
));

我还将它添加到composer.json 并运行composer dump-autoload

"autoload": {
    "classmap": [
        ...,
        "app/extensions"
    ]
},

我自己的 Confide 类似乎根本没有加载,因为 Confide 正常工作 - 从来没有 die()-ing。

如果我在包含命名空间的控制器中使用\Extensions\Confide::logAttempt($input, true);,我会得到这个ErrorException:

不应静态调用非静态方法 Extensions\Confide::logAttempt(),假设 $this 来自不兼容的上下文

我真的也需要我自己的ConfideServiceProvider 课程吗?我也试过了,但我完全不确定要放什么来让 Confide 使用我的扩展类。

没有简单的方法来扩展一个类的一小部分吗?一定有,我只是在这里遗漏了一些东西。

【问题讨论】:

    标签: php laravel laravel-4


    【解决方案1】:

    如果您希望在用户登录时执行一些代码,您应该只监听该事件。在这种情况下,我相信 Confide 使用 Auth 类登录,因此您应该能够监听该事件。

    Event::listen('auth.login', function($user)
    {
        $user->last_login = new DateTime;
        $user->save();
    });
    

    我发现这比担心扩展类更容易和更清晰。

    【讨论】:

    • 我实际上是在寻找一个可以挂钩的事件,但没有找到任何东西。我稍后会尝试,如果它有效,那确实会更干净。
    • 这是我接受的答案,因为它以更简单的方式解决了我的实际问题,尽管我要求不同的解决方案,因为我不知道更好。它有效,我正在使用它,只是将自己的类用作侦听器(如此处所述:four.laravel.com/docs/events#using-classes-as-listeners
    【解决方案2】:

    编辑:出错了

    我认为你需要这样调用方法:

    \Extensions\Confide->logAttempt($input, true);
    

    因为你正在使用:

    \Extensions\Confide::logAttempt($input, true);
    

    你如何调用静态方法。

    【讨论】:

    • 谢谢,但不幸的是这不起作用。我的控制器中没有Confide 的实例。这确实有点令人困惑。原始代码(有效)是if (Confide::logAttempt($input, true)) {...},而原始方法logAttempt 实际上不是静态的(github.com/Zizaco/confide/blob/master/src/Zizaco/Confide/…)。
    • 好吧,好像 laravel 4 在幕后使用了一些魔法,让它看起来好像你在使用静态方法,而实际上你并没有。我唯一需要做的另一件事就是将它添加到 app/config/app.php 中的别名列表中,如果您使用其中的一个用于 confide,则已经将其设置为 Extensions 目录中的命名空间点。跨度>
    • 然后只需使用别名访问confide扩展类
    • 嗯,别名Confide指向Zizaco\Confide\ConfideFacade。老实说,我也不想扩展它... :( 但是在扩展 ConfideServiceProvider 之后,它似乎或多或少地工作了。唯一的问题是,在我扩展的 logAttempt 方法中,我无法使用任何其他方法标准的 Laravel 东西,如 LogSession 或其他什么,因为那时我得到一个类似 "Class 'Extensions\Log' not found"\Illuminate\Log 的异常。我发现这有点令人沮丧。我可能只是创建一个辅助函数而不是尝试扩展 Confide。
    • 我刚刚发现我只需要添加一个反斜杠,例如\Log.
    【解决方案3】:

    我想我终于想通了。

    我不得不像这样扩展ConfideServiceProvider

    <?php
    
    namespace Extensions;
    
    class ConfideServiceProvider extends \Zizaco\Confide\ConfideServiceProvider {
    
        /**
         * Bootstrap the service provider.
         *
         * @return void
         */
        public function boot() {
            $this->package('extensions/confide');
        }
    
        /**
         * Register the application bindings.
         *
         * @return void
         */
        protected function registerConfide() {
            $this->app->bind('confide', function($app) {
                return new Confide($app->make('confide.repository'));
            });
        }
    
    }
    

    上面的代码进入app/extensions/ConfideServiceProvider.php。注意:在boot() 中,我将“zizaco”替换为“extensions”,而在registerConfide() 中,我根本没有做任何更改,但如果扩展类中不存在此方法,则将使用原始类。我不知道为什么。

    然后在app/config/app.php 中,我将Zizaco\Confide\ConfideServiceProvider 替换为Extensions\ConfideServiceProvider

    我自己的扩展 Confide 类现在看起来像这样:

    <?php
    
    namespace Extensions;
    
    class Confide extends \Zizaco\Confide\Confide {
    
        public function logAttempt($credentials, $confirmed_only = false, $identity_columns = array()) {
            $result = parent::logAttempt($credentials, $confirmed_only, $identity_columns);
            if ($result) {
                // Login successful. Do some additional stuff.
                \Log::info('User ' . \Auth::user()->username . ' logged in.');
            }
            return $result;
        }
    }
    

    注意:如果您想使用任何其他标准 Laravel 类,例如 LogSession 等,请在其前面加上一个反斜杠,如上例所示,或者为您使用的每个类添加一个 use 运算符(例如use \Log;)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-08
      • 2012-12-30
      • 1970-01-01
      • 1970-01-01
      • 2014-12-26
      • 1970-01-01
      • 2013-07-01
      相关资源
      最近更新 更多