Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/242.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.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 5.1雄辩ORM随机返回不正确的关系-*主要更新*_Php_Laravel_Laravel 5_Eloquent_Laravel 5.1 - Fatal编程技术网

Php Laravel 5.1雄辩ORM随机返回不正确的关系-*主要更新*

Php Laravel 5.1雄辩ORM随机返回不正确的关系-*主要更新*,php,laravel,laravel-5,eloquent,laravel-5.1,Php,Laravel,Laravel 5,Eloquent,Laravel 5.1,我有一个Laravel应用程序,它为一个流量适中的电子商务网站提供动力。该网站允许人们通过前端下单,但它也具有通过呼叫中心通过电话接受订单的后端功能 订单与客户相关,客户也可以是用户,用户可以是登录到前端的用户。没有用户帐户的客户只有在通过呼叫中心接受订单时才会创建 我遇到的问题非常奇怪,我相信可能是某种Laravel bug 这只是偶尔发生,但现在发生的是,当通过呼叫中心为没有用户帐户的客户下订单时,订单确认被发送给随机用户-据我所知,字面上是随机的,只是从数据库中拔出,尽管数据中没有关联 以

我有一个Laravel应用程序,它为一个流量适中的电子商务网站提供动力。该网站允许人们通过前端下单,但它也具有通过呼叫中心通过电话接受订单的后端功能

订单与客户相关,客户也可以是用户,用户可以是登录到前端的用户。没有用户帐户的客户只有在通过呼叫中心接受订单时才会创建

我遇到的问题非常奇怪,我相信可能是某种Laravel bug

这只是偶尔发生,但现在发生的是,当通过呼叫中心为没有用户帐户的客户下订单时,订单确认被发送给随机用户-据我所知,字面上是随机的,只是从数据库中拔出,尽管数据中没有关联

以下是项目中模型的相关部分:

class Order extends Model
{
    public function customer()
    {
        return $this->belongsTo('App\Customer');
    }
}

class Customer extends Model
{
    public function orders()
    {
        return $this->hasMany('App\Order');
    }

    public function user()
    {
        return $this->belongsTo('App\User');
    }
}

class User extends Model
{ 
    public function customer()
    {
        return $this->hasOne('App\Customer');
    }
}
以下是上述数据库迁移(为简洁起见进行了编辑):

发送订单确认的逻辑在一个事件处理程序中,该事件处理程序在订单支付后被触发

以下是
OrderSuccess
事件(为简洁起见进行了编辑):

如图所示,此事件通过一个
Order
model对象传递

以下是事件处理程序(为简洁起见进行了编辑):

检查
$order->customer->user
对象是否为空,如果为真,则发送订单确认。如果为空(通常为空),则不发送确认

从上面可以看出,我添加了一个日志来记录发送电子邮件时的对象。下面是一个错误的示例(为了简洁起见,再次截断):

如您所见,
Customer
没有用户id,但Laravel返回了一个
user
对象

更重要的是,如果我手动触发完全相同的
OrderSuccess
事件,则上述内容不可复制-它不会发送电子邮件,也不会加载
用户
对象

正如我之前所说,这个问题很少发生——通过呼叫中心,没有用户帐户的客户平均每天大约有40个订单,突出显示的问题可能每周只发生一到两次

我对Laravel不够熟悉,不知道这里可能存在什么问题-是某种形式的模型缓存、雄辩的ORM问题还是系统中的其他小精灵

任何想法都值得赞赏-如果这似乎是某种形式的bug,我可能会在Laravel github问题跟踪器中发布这个问题

更新关于提出的一些答案/评论,我已尝试消除任何潜在的有说服力的ORM问题,手动检索数据,如下所示:

$customer = Customer::find($order->customer_id);
$user = User::find($customer->user_id);

if(!is_null($user)) {
    // send email and log actions etc
}
以上仍然产生相同的随机结果-即使客户没有
用户id
(在本例中为NULL),也会检索不相关的用户

更新2由于第一次更新没有任何帮助,我恢复使用最初的“顺序”方法。为了尝试另一种解决方案,我将事件代码从事件处理程序中取出,并将其放在我的控制器中-我之前使用
event::fire(newordersuccess($order)),由OrderSuccess事件触发,我将这行注释掉,并将事件处理程序代码放在控制器方法中:

$order = Order::find($order_id);

//Event::fire(new OrderSuccess ($order));

// code from the above event handler
$order->paid = date('Y-m-d H:i:s');
$order->save();

if(!is_null($order->customer->user)) {

    App_log::add('customer_order_success_email_sent', 'Handlers\Events\OrderSuccessProcess\handle', $order->id, print_r($order->customer, true).PHP_EOL.print_r($order->customer->user, true));

    // email the user the order confirmation
    Mail::send('emails.order_success', ['order' => $order], function($message) use ($order)
    {
        $message->to($order->customer->user->email, $order->customer->first_name.' '.$order->customer->last_name)->subject('Order #'.$order->id.' confirmation');
    });
}
上述变更已经在生产现场进行了一个多星期了——自从变更后,就再也没有出现过一次此类问题

我能得出的唯一可能的结论是,Laravel事件系统中存在某种缺陷,以某种方式破坏了传递的对象。或者会有其他的事情在起作用吗

更新3 我现在说将代码移到活动之外解决了这个问题似乎为时过早——事实上,通过我的日志记录,在过去的2天里,我可以看到发送了更多错误的订单确认(总共5次,在几乎3周没有问题之后)

我注意到,收到恶意订单确认的用户ID似乎在增加(不是没有间隙,而是以升序)

我还注意到,每个有问题的订单都是通过现金和账户信用支付的——大多数订单都是现金支付的。我进一步研究了这一点,用户ID实际上是相关信用交易的ID

以上是解决这一问题的第一个突破。仔细检查后,我发现问题仍然是随机的——有相当多(至少50%)的订单是通过帐户信用为客户支付的,没有用户帐户,但没有导致发送错误的电子邮件(尽管相关的信用交易id与用户id匹配)

所以,这个问题仍然是随机的,或者看起来是随机的。我的信用赎回事件是这样触发的:

Event::fire(new CreditRedemption( $credit, $order ));
上面的调用正好在我的
orderssuccess
事件之前-如您所见,这两个事件都传递给
$order
模型对象

我的
CreditRedemption
事件处理程序如下所示:

public function handle(CreditRedemption $event)
{
    // make sure redemption amount is a negative value
    if($event->credit < 0) {
        $amount = $event->credit;
    }
    else {
        $amount = ($event->credit * -1);
    }

    // create the credit transaction
    $credit_transaction = New Credit_transaction();
    $credit_transaction->transaction_type = 'Credit Redemption';
    $credit_transaction->amount = $amount; // negative value
    $credit_transaction->customer_id = $event->order->customer->id;
    $credit_transaction->order_id = $event->order->id;

    // record staff member if appropriate
    if(!is_null($event->order->staff)) {
        $credit_transaction->staff_id = $event->order->staff->id;
    }

    // save transaction
    $credit_transaction->save();

    return $credit_transaction;
}
公共函数句柄(CreditRedemption$事件)
{
//确保赎回金额为负值
如果($event->credit<0){
$amount=$event->credit;
}
否则{
$amount=($event->credit*-1);
}
//创建信用交易记录
$credit_transaction=新的credit_transaction();
$credit_transaction->transaction_type='信用赎回';
$credit\u transaction->amount=$amount;//负值
$credit\u transaction->customer\u id=$event->order->customer->id;
$credit\u transaction->order\u id=$event->order->id;
//记录工作人员(如适用)
如果(!为空($event->order->staff)){
$credit\u transaction->staff\u id=$event->order->staff->id;
}
//保存事务
$credi
$customer = Customer::find($order->customer_id);
$user = User::find($customer->user_id);

if(!is_null($user)) {
    // send email and log actions etc
}
$order = Order::find($order_id);

//Event::fire(new OrderSuccess ($order));

// code from the above event handler
$order->paid = date('Y-m-d H:i:s');
$order->save();

if(!is_null($order->customer->user)) {

    App_log::add('customer_order_success_email_sent', 'Handlers\Events\OrderSuccessProcess\handle', $order->id, print_r($order->customer, true).PHP_EOL.print_r($order->customer->user, true));

    // email the user the order confirmation
    Mail::send('emails.order_success', ['order' => $order], function($message) use ($order)
    {
        $message->to($order->customer->user->email, $order->customer->first_name.' '.$order->customer->last_name)->subject('Order #'.$order->id.' confirmation');
    });
}
Event::fire(new CreditRedemption( $credit, $order ));
public function handle(CreditRedemption $event)
{
    // make sure redemption amount is a negative value
    if($event->credit < 0) {
        $amount = $event->credit;
    }
    else {
        $amount = ($event->credit * -1);
    }

    // create the credit transaction
    $credit_transaction = New Credit_transaction();
    $credit_transaction->transaction_type = 'Credit Redemption';
    $credit_transaction->amount = $amount; // negative value
    $credit_transaction->customer_id = $event->order->customer->id;
    $credit_transaction->order_id = $event->order->id;

    // record staff member if appropriate
    if(!is_null($event->order->staff)) {
        $credit_transaction->staff_id = $event->order->staff->id;
    }

    // save transaction
    $credit_transaction->save();

    return $credit_transaction;
}
Schema::create('customers', function(Blueprint $table)
    {
        $table->increments('id');
        $table->integer('user_id')->nullable();
        $table->foreign('user_id')->references('id')->on('users');

        $table->string('first_name');
        $table->string('last_name');
        $table->string('telephone')->nullable();
        $table->string('mobile')->nullable();
        $table->timestamps();
        $table->softDeletes();
    });



Schema::create('orders', function(Blueprint $table)
{
   $table->increments('id');
   $table->integer('payment_id')->nullable()->index();

   $table->integer('customer_id')->nullable();
   $table->foreign('customer_id')->references('id')->on('customers');
   $table->integer('staff_id')->nullable()->index();
   $table->decimal('total', 10, 2);
   $table->timestamps();
   $table->softDeletes();
    });
$customer->save();
$customer->user->save($user);
$user_exists = $order->customer()->user();

if($user_exists)
{
    //email whatever
}
class Order extends Model
{
    public function customer()
    {
        return $this->belongsTo('App\Customer', 'foreign_key', 'id');
    }
}
->unsigned()
$table->integer('user_id')->unsinged()->index();
$table->integer('user_id')->index()->nullable();
$customer = Customer::find($order->customer_id);
$user = User::find($customer->user_id);

if(!is_null($user)) {
    // send email and log actions etc
}
$customer = Customer::whereNotNull('user_id')->find($order->customer_id); 

if (!$customer->isEmpty()) { 
    // send email and log actions etc 
}