Laravel: Eloquent convierte el parámetro de consulta en un número entero antes de la comparación

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

  •  20-12-2019
  •  | 
  •  

Pregunta

Estoy intentando devolver una sola fila de una tabla basada en la clave principal.

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

Por alguna razón $idorSKU se está convirtiendo a y (int) antes de que ocurra la comparación.Por ejemplo, cuando $isOrSKU = "9dfghfd", se devuelve la fila con ID=9.¿Por qué es esto?¡No debería devolver nada en absoluto!¿Alguien puede explicar esto?

Aquí está el esquema de tabla relevante.

| id                         | int(10) unsigned | NO   | PRI | NULL      
| name                       | varchar(255)     | NO   |     | NULL                
| sku                        | varchar(255)     | NO   |     | NULL 
¿Fue útil?

Solución

Esto está relacionado con la base de datos, no con Laravel, encasillando su cadena.Porque estás haciendo una consulta sobre un int(10) columna, MySQL está cambiando a la fuerza su cadena de búsqueda a una int, haciendo que su consulta se convierta en 9.

Puedo confirmar lo siguiente:

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

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

Por lo tanto su variable de 9dfghfd porque encasillado a int (9).Pero si su variable fuera "df9ghfd", no estaría encasillada y no coincidiría.

Editar:El problema afecta a otras cosas, como el enlace del modelo de ruta:

domain.com/product/1

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

Abrí un ticket en Github para discutirlo más a fondo. - así que consulte aquí para obtener más información/discusión.

Pero en general el problema no es culpa directa de Laravel.

Editar:Parece que el problema afecta a GitHub. sí mismo:

Esto funciona: https://github.com/laravel/framework/issues/5254

Y esto también: https://github.com/laravel/framework/issues/5254typecast

Otros consejos

Resulta que aquí, usando PostgreSQL, funciona diferente a tu base de datos, cuando yo lo hago:

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

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

Recibo este error:

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)

Entonces Laravel, sabiendo que es una columna de números enteros, la pasa directamente a la base de datos sin comillas, lo que genera una excepción en la base de datos, ya que PostgreSQL ni siquiera intentará convertir esa cadena a un número entero.

Entonces, incluso si recibes ayuda de los desarrolladores principales de Laravel, creo que siempre deberías hacer algo como esto para ayudarte a realizar esas búsquedas mixtas:

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();
});
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top