Laravel - Éloquent convertit le paramètre de requête en entier avant de la comparaison

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

  •  20-12-2019
  •  | 
  •  

Question

Je suis en train de retourner une seule ligne d'une table basée sur la clé primaire.

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

Pour une raison quelconque $idorSKU est converti (int) avant que la comparaison se passe.Par exemple, lorsque $isOrSKU = "9dfghfd", en ligne avec l'ID=9 est retourné.Pourquoi est-ce?Il doit retourner rien du tout!Quelqu'un peut-il expliquer cela?

Ici est le schéma de la table de

| id                         | int(10) unsigned | NO   | PRI | NULL      
| name                       | varchar(255)     | NO   |     | NULL                
| sku                        | varchar(255)     | NO   |     | NULL 
Était-ce utile?

La solution

Ceci est lié à la base de données, pas de Laravel, typecasting de votre chaîne.Parce que vous faites une requête sur une int(10) colonne, mySQL est forcably changer votre chaîne de recherche pour une int, à l'origine de votre requête pour devenir 9.

Je peux confirmer ce qui suit:

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

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

Par conséquent, votre variable d' 9dfghfd parce que catalogués à int (9).Mais si votre variable est "df9ghfd" - il ne serait pas enfermé, et il l'habitude de match.

Edit:Le problème touche aussi d'autres choses, comme la Route de la liaison de modèle:

domain.com/product/1

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

J'ai ouvert un ticket sur Github pour en discuter - vérifiez ici pour plus d'informations et de discussion.

Mais dans l'ensemble, le problème n'est pas directement la faute de Laravel.

Edit:semble que le problème affecte GitHub lui-même:

Ceci fonctionne: https://github.com/laravel/framework/issues/5254

Et donc cela: https://github.com/laravel/framework/issues/5254typecast

Autres conseils

S'avère qu'ici, l'utilisation de PostgreSQL, il fonctionne différemment de votre base de données, lorsque je fais:

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

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

J'obtiens cette erreur:

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)

Donc, Laravel, sachant que c'est une colonne de type entier, est en train de passer directement à la base de données sans les guillemets, ce qui génère une base de données d'exception, depuis PostgreSQL va même pas essayer de lancer cette chaîne en entier.

Donc, même si vous obtenir de l'aide de Laravel les développeurs du noyau, je pense que vous devriez toujours faire quelque chose de ce genre pour vous aider à faire ces mixtes seaches:

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();
});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top