Laravel - يقوم Eloquent بتحويل معلمة الاستعلام إلى عدد صحيح قبل المقارنة

StackOverflow https://stackoverflow.com//questions/25008004

  •  20-12-2019
  •  | 
  •  

سؤال

أحاول إرجاع صف واحد من جدول بناءً على المفتاح الأساسي.

    $product = Product::where('id', '=', $idOrSKU)
        ->orWhere('sku', '=', $idOrSKU)
        ->take(1)->get();

لسبب ما $idorSKU يتم تحويله إلى و (int) قبل أن تتم المقارنة.على سبيل المثال، متى $isOrSKU = "9dfghfd", ، يتم إرجاع الصف ذو المعرف = 9.لماذا هذا؟يجب أن لا يعود أي شيء على الإطلاق!يمكن للشخص أن يفسر هذا؟

هنا هو مخطط الجدول ذي الصلة

| id                         | int(10) unsigned | NO   | PRI | NULL      
| name                       | varchar(255)     | NO   |     | NULL                
| sku                        | varchar(255)     | NO   |     | NULL 
هل كانت مفيدة؟

المحلول

يرتبط هذا بقاعدة البيانات، وليس Laravel، الذي يقوم بتلبيس سلسلتك.لأنك تقوم بالاستعلام على int(10) العمود، يقوم MySQL بتغيير سلسلة البحث الخاصة بك بالقوة إلى int, ، مما يتسبب في أن يصبح الاستعلام الخاص بك 9.

أستطيع أن أؤكد ما يلي:

$test1 = Test::find('1');
echo $test1->id; // gives 1

$test2 = Test::find('1example');
echo $test2->id; // gives 1

ولذلك المتغير الخاص بك من 9dfghfd لأن التلبيس ل int (9).ولكن إذا كان المتغير الخاص بك هو "df9ghfd" - فلن يتم كتابته، ولن يتطابق.

يحرر:تؤثر المشكلة على أشياء أخرى، مثل ربط نموذج المسار:

domain.com/product/1

domain.com/product/1thisalsoworks // takes you to the page of ID 1

لقد فتحت تذكرة على Github لمناقشة الأمر بشكل أكبر - لذا تحقق هنا لمزيد من المعلومات/المناقشة.

لكن المشكلة بشكل عام ليست خطأً مباشرًا في Laravel.

يحرر:يبدو أن المشكلة تؤثر على GitHub بحد ذاتها:

هذا يعمل: https://github.com/laravel/framework/issues/5254

وهكذا يفعل هذا: https://github.com/laravel/framework/issues/5254typecast

نصائح أخرى

اتضح أنه هنا، باستخدام PostgreSQL، فإنه يعمل بشكل مختلف عن قاعدة البيانات الخاصة بك، عندما أفعل:

Route::any('test', function()
{
    $code = '181rerum';

    return Ad::where('id', $code)->orWhere('company_code', $code)->first();
});

أحصل على هذا الخطأ:

SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input 
syntax for integer: "181rerum" (SQL: select * from "ads" where 
"id" = 181rerum or "company_code" = 181rerum limit 1)

لذا، فإن Laravel، مع العلم أنه عمود عدد صحيح، يقوم بتمريره مباشرةً إلى قاعدة البيانات بدون علامات اقتباس، مما يؤدي إلى إنشاء استثناء في قاعدة البيانات، نظرًا لأن PostgreSQL لن يحاول حتى تحويل هذه السلسلة إلى عدد صحيح.

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

Route::any('test/{id}', function($id)
{
    /// You can always filter by a string here

    $q = Ad::where('company_code', $id);

    /// You just try to filter by id if the search string is entirely numeric

    if (is_numeric($id))
    {
        $q->orWhere('id', $id);
    }

    return $q->first();
});
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top