foreach المشكلة عند استخدام php MVC / ajax / json لحذف سجلات متعددة

0

أقوم بإدراج جدول يوضح السجلات من قاعدة البيانات ويحتوي كل صف على مربع اختيار له قيمة معرّف مرتبطة به.

<label class="m-checkbox">
 <input type="checkbox" name="order_id[]" value="<?php echo sanitize($failed->order_id); ?>">
 <span></span>
</label>

بمجرد أن يحدد المستخدم مربعات الاختيار للسجلات التي يريد حذفها ، يتم الضغط على زر الإرسال ويؤدي ذلك إلى طلب ajax.

$( '.delete-failed' ).on('click', function(e) {
    e.preventDefault();
    var form = $( '#delete-failed' ).serialize();
    $.ajax({
        url: url + '/TransactionsAjax/deleteFailedTransactions',
        type: 'POST',
        data: form,
        dataType: 'json',
        beforeSend: function() {
            $( 'delete-failed' ).prop('disabled', true);
        }
    })
    .done(function (data) {
        if(!data.success) {
            $( '.alert-danger' ).append(data.message).fadeIn();

        } else {


            $( '.alert-success' ).append(data.message).fadeIn();
        }
    })
            .fail(function (jqXHR, textStatus, errorThrown) {
            console.log(textStatus + ': ' + errorThrown);
            console.warn(jqXHR.responseText);
        });
});

ثم يذهب إلى وحدة التحكم:

if($_SERVER['REQUEST_METHOD'] === 'POST') {

    $response = array();
    $message = '';


    $orderId = $_POST['order_id'];

    $data = [

        'order_id' => $orderId
    ];

    if($this->TransactionsModel->deleteFailedTransactions($data)) {
        $response['success'] = true;
        $response['message'] = 'Failed transactions deleted';

    } else {

        $response['success'] = false;
        $response['message'] = 'Something went wrong. Please try again later.';
    }

    echo json_encode($response);    
}

والذي من المفترض أن يرسل البيانات إلى النموذج:

public function deleteFailedTransactions($data)
    {
        $this->db->beginTransaction();

        try {

            $this->db->query("DELETE FROM `order_summary` WHERE `order_id` = :order_id");
            $this->db->bind(":order_id", $order_id);

            foreach($data as $item) {
                $order_id = $item['order_id'];
                $this->db->execute();
            }


            $this->db->query("DELETE FROM `order_detail` WHERE `order_id` = :order_id");
            $this->db->bind(":order_id", $order_id);

            foreach($data as $item) {
                $order_id = $item['order_id'];
                $this->db->execute();
            }

            $this->db->commit();
            return true;
        }

        catch(Exception $e) {
            $this->db->rollBack();
            echo $e;
            return false;
        }
    }

الخطأ الذي أحصل عليه في وحدة التحكم هو:

undefined index: order_id

إنه يشير إلى هذا السطر في النموذج:

$order_id = $item['order_id'];

لست متأكدًا من النقطة التي تكون فيها المشكلة ، هل هي في البيانات التي يتم إرسالها عبر ajax ، في حالة وجود حلقة foreach في وحدة التحكم بدلاً من ذلك .. لست متأكدًا.

1 إجابة

0

تنبع المشكلة من سوء التعامل مع البيانات وأسماء المتغيرات. أي التفكير في كيفية التفاف البيانات وتمريرها. هل تنوي تمرير معرف طلب واحد من مربعات الاختيار في كل مرة في ajax ، أو متعددة؟ إنه غير واضح ، لذلك قمت بتعديل الرمز للتعامل مع معرف طلب واحد. إذا كان متعددًا ، فأنت بحاجة إلى التكرار في وحدة التحكم وإنشاء مجموعة من معرّفات الطلب بشكل صحيح من المشاركة ، ثم الوصول إلى حلقة مناسبة لكل معرف طلب في النموذج بشكل صحيح وربط وتنفيذ الاستعلام لكل منها. تأكد من أنك تحلق فوق الكائن الذي يحمل قائمة المعرفات بالفعل.

لمسألة واحدة ، في نموذجك $order_id غير موجود ، لقد مررت فقط في $data متغير ، قد تبحث عنه $data['order_id'] أو ببساطة المرور $order_id دون تضمينها في $data مجموعة مصفوفة.

وبالمثل ، يبدو أن متغير البيانات $ هذا مجرد مصفوفة تحتوي على order_id واحد. ليس من المنطقي الوصول إلى حلقة على بيانات $ عندما يتم تشفيرها لاحتواء مفتاح واحد ، زوج قيمة.

سأحاول هذا:

if($_SERVER['REQUEST_METHOD'] === 'POST') {

  $response = array();
  $message = '';

  $orderId = $_POST['order_id'];

  if($this->TransactionsModel->deleteFailedTransactions($orderId)) {
    $response['success'] = true;
    $response['message'] = 'Failed transactions deleted';

  } else {

    $response['success'] = false;
    $response['message'] = 'Something went wrong. Please try again later.';
  }

  echo json_encode($response);    
}

ثم النموذج:

public function deleteFailedTransactions($order_id)
{
    $this->db->beginTransaction();

    try {

        $this->db->query("DELETE FROM `order_summary` WHERE `order_id` = :order_id");
        $this->db->bind(":order_id", $order_id);

        $this->db->execute();

        $this->db->query("DELETE FROM `order_detail` WHERE `order_id` = :order_id");
        $this->db->bind(":order_id", $order_id);

        $this->db->execute();

        $this->db->commit();
        return true;
    }

    catch(Exception $e) {
        $this->db->rollBack();
        echo $e;
        return false;
    }
}

رؤية هتمل لديك order_id[] يشير إلى أنك قد تحاول إرسال رسائل متعددة. اعتمادًا على كيفية تمرير البيانات ، قد تحتاج إلى تفجير / تفجير القائمة بشكل مختلف عني. اعتبر هذا:

if($_SERVER['REQUEST_METHOD'] === 'POST') {

  $response = array();
  $message = '';

  $orderIds = $_POST['order_id']; //explode maybe

  if($this->TransactionsModel->deleteFailedTransactions($orderIds)) {
    $response['success'] = true;
    $response['message'] = 'Failed transactions deleted';

  } else {

    $response['success'] = false;
    $response['message'] = 'Something went wrong. Please try again later.';
  }

  echo json_encode($response);    
}

ثم النموذج:

public function deleteFailedTransactions($order_id)
{
    $this->db->beginTransaction();

    try {
        foreach($order_id as $id) {
          $this->db->query("DELETE FROM `order_summary` WHERE `order_id` = :order_id");
          $this->db->bind(":order_id", $id);

          $this->db->execute();
        }

        foreach($order_id as $id) {
          $this->db->query("DELETE FROM `order_detail` WHERE `order_id` = :order_id");
          $this->db->bind(":order_id", $id);

          $this->db->execute();
        }

        $this->db->commit();
        return true;
    }

    catch(Exception $e) {
        $this->db->rollBack();
        echo $e;
        return false;
    }
}

وقد تفكر في تحسين استعلامات foreach في واحد لكل منها ، مثل هذا:

  $this->db->query("DELETE FROM `order_summary` WHERE `order_id` IN (:order_id)");
  $this->db->bind(":order_id", implode(",",$order_id); //whatever gives you comma separated string
  $this->db->execute();

لاحظ أنني لا أقوم بتشغيل هذا الرمز ، لذا اعتبره توجيهًا / كودًا زائفًا موجهًا لـ PHP لتتمكن من اكتشافه بنفسك. لا تتردد في طرح أسئلة توضيحية عبر DM.

:مؤلف

أسئلة ذات صلة

فوق
قائمة طعام