web-dev-qa-db-fra.com

Échapper aux requêtes SQL brutes dans Laravel 4

Comment échapper les paramètres passés à une requête brute dans Laravel 4? Je m'attendais à quelque chose comme DB::escape() (qui sonne une cloche de Laravel 3) et j'ai également essayé DB::quote() (que je pensais être disponible via l'objet PDO )

$query = DB::select("SELECT * FROM users WHERE users.id = " . DB::escape($userId));

Nous ne pouvons pas utiliser la méthode select avec des espaces réservés car ce qui précède n'est qu'un exemple simplifié de ce que nous essayons de réaliser. Nous avons une grande requête personnalisée avec quelques requêtes select imbriquées qui ne peut pas être adapté au générateur de requêtes.

Quelle est la meilleure approche pour échapper à quelque chose avant de l'insérer dans Laravel 4?

ÉDITER:

Je viens de découvrir que vous pouvez accéder à l'objet PDO et utiliser la fonction de devis de cette façon. Est-ce toujours la meilleure approche ou existe-t-il un moyen plus simple d'accéder à cette fonction?

DB::connection()->getPdo()->quote("string to quote");
31
Dwight

Vous pouvez citer vos chaînes de cette façon, à travers la façade DB.

DB::connection()->getPdo()->quote("string to quote");

J'ai mis cette réponse dans ma question quand je l'ai découverte, mais je l'ai maintenant mise en tant que réponse réelle pour la rendre plus facile à trouver pour les autres.

56
Dwight
$value = Input::get("userID");

$results = DB::select( DB::raw("SELECT * FROM users WHERE users.id = :value"), array(
   'value' => $value,
 ));

Plus de détails ICI

19
Arun Kumar M

Vous pouvez également essayer ceci, ( Lire la documentation )

$results = DB::select('SELECT * FROM users WHERE users.id = ?', array($userId));
9
The Alpha

J'ai trouvé cette question lors de la recherche de sql générique s'échappant dans Laravel. Ce dont j'avais réellement besoin, c'était d'un nom de table/colonne s'échappant. Donc, pour référence future:

/**
 * Quotes database identifier, e.g. table name or column name. 
 * For instance:
 * tablename -> `tablename`
 * @param  string $field 
 * @return string      
 */
function db_quote_identifier($field) {
  static $grammar = false;
  if (!$grammar) {
    $grammar = DB::table('x')->getGrammar(); // The table name doesn't matter.
  }
  return $grammar->wrap($field);
}
4
Rafał G.

J'utilise ceci dans mon helpers.php à Laravel 5:

if ( ! function_exists('esc_sql'))
{
    function esc_sql($string)
    {
        return app('db')->getPdo()->quote($string);
    }
}

Ensuite, je peux utiliser esc_sql fonction où je dois effectuer une fuite pour les requêtes SQL brutes.

3
J. Bruni

Deux réponses ici, que j'utilise, ont des solutions moins verbeuses intégrées dans la façade DB.

Tout d'abord, valeur citant :

// From linked answer
DB::connection()->getPdo()->quote("string to quote");
// In the DB facade
DB::getPdo()->quote('string to quote');

Deuxièmement, identifiant entre guillemets (noms des tables et des colonnes):

// From linked answer
DB::table('x')->getGrammar()->wrap('table.column');
// In the DB facade
DB::getQueryGrammar()->wrap('table.column');
0
Sonny

Voici un exemple plus complet, montrant comment échapper à la fois les valeurs et les colonnes et étendre le constructeur de requêtes de Laravel:

<?php

namespace App\Providers;

use Illuminate\Database\Query\Builder;
use Illuminate\Support\ServiceProvider;


class DatabaseQueryBuilderMacroProvider extends ServiceProvider {

    public function register() {
        Builder::macro('whereInSet', function($columnName, $value) {
            /** @var \Illuminate\Database\Query\Grammars\Grammar $grammar */
            $grammar = $this->getGrammar();
            return $this->whereRaw('FIND_IN_SET(?,' . $grammar->wrap($columnName) . ')', [$value]);
        });
    }
}
0
mpen