Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/243.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在何处放置Laravel侦听器逻辑_Php_Laravel - Fatal编程技术网

Php 在何处放置Laravel侦听器逻辑

Php 在何处放置Laravel侦听器逻辑,php,laravel,Php,Laravel,我想在用户注册时关联订单(用户会话中保存的ID) 我已经创建了一个事件和一个侦听器,如Laravel站点中记录的那样。我遇到的问题是,我不确定关联记录的逻辑应该放在哪里,我最初将其放在Order Controller中,但应用程序会尝试引用Builder::attachOrderToUser 我将该方法移到了我的模型中,它起了作用,但现在我发现了错误: 调用未定义的方法Illumb\Database\Query\Builder::attach() 有人能指出这一逻辑究竟应该走向何方吗 订单模型中

我想在用户注册时关联订单(用户会话中保存的ID)

我已经创建了一个事件和一个侦听器,如Laravel站点中记录的那样。我遇到的问题是,我不确定关联记录的逻辑应该放在哪里,我最初将其放在
Order Controller
中,但应用程序会尝试引用Builder::attachOrderToUser

我将该方法移到了我的模型中,它起了作用,但现在我发现了错误:

调用未定义的方法Illumb\Database\Query\Builder::attach()

有人能指出这一逻辑究竟应该走向何方吗

订单模型中的方法:

/**
 * Attach Order to Customer
 *
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public static function attachOrderToUser($order_id, $user_id)
{
    // @TODO: Wrap around event handler
    $user = User::find($user_id);

    if($user->order()->attach($order_id))
        return true;
    else
        return false;

}
以下是我的侦听器代码:

namespace App\Listeners;

use App\Events\UserQuickSignUpComplete;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

use Auth;
use Session;
use App\Order;
use Illuminate\Http\Request; 

class AttachGuestOrderToUser
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  UserQuickSignUpComplete  $event
     * @return void
     */
    public function handle(UserQuickSignUpComplete $event)
    {
        // get currently logged in user (was signed in on method that triggers event)
        $user = Auth::user();
        // get order
        $order = Session::get('last_transaction.order_id');
        // attach order to user
        Order::attachOrderToUser($order['order_id'], $user['id']);
    }
}

任何其他建议也将不胜感激

将两个对象连接在一起对我来说是一种服务。那么,问题是这样的服务应该去哪里。控制器感觉不对劲,因为我们无法控制用户操作。存储库感觉不对劲,因为我们处理的是两个独立的模型实例(而不是同一类模型的集合)

但请查看事件侦听器的名称:
\App\Listeners\AttachGuestOrderToUser
。这是一个非常具体的名字,暗示着一个具体的工作。在我看来,那个类已经是一种服务了。所以我只想把你所需要的逻辑放在这个听者里面

namespace App\Listeners;

use App\Events\UserQuickSignUpComplete;

class AttachGuestOrderToUser
{
    /**
     * You guessed it: attach a guest order to a specific user.
     *
     * @param  UserQuickSignUpComplete  $event
     * @return void
     */
    public function handle(UserQuickSignUpComplete $event)
    {
        \Auth::user()->order()->attach(\Session::get('last_transaction.order_id'));
    }
}

一般来说,事件侦听器是一种特定类型的服务,因此这对未来的代码读者来说应该是有意义的。

为什么使用间接寻址?在
handle
中,您可以
Auth::user()->order()->附加(Session::get('last\u transaction.order\u id'))
并进行集成测试以确认行为。尝试
$user->order
而不是
$user->order()
@bishop逻辑应该直接进入句柄吗?我认为最好的做法是将其保存在控制器或存储库中?最好的做法是分离关注点,在每个代码单元中做一件事。有时,遵循这种做法意味着将代码放入控制器中。有时会被放入存储库。有时,事件处理程序是一个专门的服务。在我看来,这段代码是一项服务,因此逻辑可以合法地进入事件处理程序。@bishop感谢您的回复,请为我创建一个答案,以标记因为逻辑在侦听器句柄中,我们如何在phpunit中测试它?@Imran
new AttachGuestOrderToUser
,调用
handle
,使用测试数据,并让
\Auth
模拟其用户调用。