Laravel – Eloquent konvertiert den Abfrageparameter vor dem Vergleich in eine Ganzzahl

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

  •  20-12-2019
  •  | 
  •  

Frage

Ich versuche, eine einzelne Zeile aus einer Tabelle basierend auf dem Primärschlüssel zurückzugeben.

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

Aus irgendeinem Grund $idorSKU wird in und umgewandelt (int) bevor der Vergleich stattfindet.Zum Beispiel wann $isOrSKU = "9dfghfd", wird die Zeile mit der ID=9 zurückgegeben.Warum ist das?Es sollte überhaupt nichts zurückgeben!Kann das jemand erklären?

Hier ist das entsprechende Tabellenschema

| id                         | int(10) unsigned | NO   | PRI | NULL      
| name                       | varchar(255)     | NO   |     | NULL                
| sku                        | varchar(255)     | NO   |     | NULL 
War es hilfreich?

Lösung

Dies hängt mit der Typumwandlung Ihrer Zeichenfolge durch die Datenbank zusammen, nicht durch Laravel.Weil Sie eine Abfrage zu einem durchführen int(10) Spalte, mySQL ändert Ihre Suchzeichenfolge zwangsweise in eine int, wodurch Ihre Anfrage zu wird 9.

Folgendes kann ich bestätigen:

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

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

Daher Ihre Variable von 9dfghfd weil typisiert zu int (9).Wenn Ihre Variable jedoch „df9ghfd“ wäre, würde sie nicht typisiert werden und nicht übereinstimmen.

Bearbeiten:Das Problem betrifft andere Dinge, wie z. B. die Routenmodellbindung:

domain.com/product/1

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

Ich habe ein Ticket auf Github eröffnet, um weiter darüber zu diskutieren - Weitere Informationen/Diskussionen finden Sie hier.

Aber insgesamt ist das Problem nicht direkt auf Laravel zurückzuführen.

Bearbeiten:Es scheint, dass das Problem GitHub betrifft selbst:

Das funktioniert: https://github.com/laravel/framework/issues/5254

Und das gilt auch für Folgendes: https://github.com/laravel/framework/issues/5254typecast

Andere Tipps

Es stellt sich heraus, dass es hier mit PostgreSQL anders funktioniert als mit Ihrer Datenbank, wenn ich Folgendes tue:

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

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

Ich erhalte diesen Fehler:

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)

Da Laravel weiß, dass es sich um eine Integer-Spalte handelt, übergibt es diese direkt ohne Anführungszeichen an die Datenbank, was eine Datenbankausnahme generiert, da PostgreSQL nicht einmal versucht, diese Zeichenfolge in eine Integer-Spalte umzuwandeln.

Selbst wenn Sie Hilfe von Laravel-Kernentwicklern erhalten, sollten Sie meiner Meinung nach immer so etwas tun, um diese gemischten Suchen durchzuführen:

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();
});
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top