Entgehen Sie rohen SQL-Abfragen in Laravel 4

Lesezeit: 5 Minuten

Benutzer-Avatar
Dwight

Wie geht man vor, um Parameter zu maskieren, die an eine Rohabfrage in Laravel 4 übergeben werden? Ich habe so etwas erwartet DB::escape() (was eine Glocke von Laravel 3 läutet) und auch versucht DB::quote() (von dem ich dachte, dass es über die verfügbar sein könnte PDO-Objekt)

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

Wir können die select-Methode nicht mit Platzhaltern verwenden, da das obige nur ein vereinfachtes Beispiel dafür ist, was wir erreichen wollen. Wir haben eine große benutzerdefinierte Abfrage mit einigen verschachtelten Auswahlabfragen, die nicht an den Abfragegenerator angepasst werden können.

Was ist der beste Ansatz, um etwas zu entkommen, bevor es in Laravel 4 eingefügt wird?

BEARBEITEN:

Ich habe gerade entdeckt, dass Sie auf das PDO-Objekt zugreifen und die Zitatfunktion auf diese Weise verwenden können. Ist dies immer noch der beste Ansatz oder gibt es einen einfacheren Weg, auf diese Funktion zuzugreifen?

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

  • Vielen Dank. +1 für die Aufnahme der Lösung (Sie hätten sie auch separat als Antwort posten und akzeptieren können … könnte uns etwas Zeit sparen)

    – J. Bruni

    7. April 2014 um 0:05 Uhr


  • @J.Bruni, guter Punkt! Ich habe es jetzt auch als tatsächliche Antwort hinzugefügt, damit es einfacher zu finden sein sollte.

    – Dwight

    22. April 2014 um 0:36 Uhr

Sie können Ihre Zeichenfolgen auf diese Weise durch die zitieren DB Fassade.

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

Ich habe diese Antwort in meine Frage eingefügt, als ich sie entdeckte, aber ich habe sie jetzt als tatsächliche Antwort eingefügt, damit andere sie leichter finden können.

  • Vielen Dank! Es ist erstaunlich, wie unnachgiebig die Leute darauf sind, die falsche Frage zu beantworten. Ich brauche die gleiche Antwort wie Sie, und Parameter funktionieren auch in meiner Situation nicht.

    – Gabriel Magana

    28. April 2014 um 23:16 Uhr

  • Funktioniert, aber so lange anzurufen! DB::escape() wäre schön.

    – Andreas

    10. März 2018 um 3:19 Uhr

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

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

Mehr Details HIER

  • Dies beantwortet die Frage nicht, es besagt, dass ich nicht mit Platzhaltern nach der Lösung gesucht habe, sondern nach dem geeigneten Weg, um eine Variable zu maskieren.

    – Dwight

    24. September 2013 um 1:24 Uhr

  • @Dwight: Wie strittig ist. Wenn Sie es verlassen, um den Variablenwert tatsächlich als SQL zu codieren, tut dies auch der Platzhalter. PDO auch.

    – hakre

    11. Mai 2014 um 8:49 Uhr

  • Vorsicht, ich hatte Probleme, dies in Kombination mit anderen zu verwenden where Aussagen. Der Abfragegenerator kombiniert die Platzhalter in der nicht select() und die anderen dynamischen Ersetzungen wie in der where.

    – Tomvo

    22. Juli 2015 um 15:22 Uhr

  • @hakre Was ist, wenn ich eine Reihe (eine variable Anzahl) von Variablen maskieren muss, um sie in einen “IN ()” -Teil einer Anweisung einzufügen?

    – Janis Elmeris

    4. Dezember 2016 um 17:00 Uhr


  • @Janis: Antworten auf solche Fragen finden Sie unter Kann ich ein Array an eine IN()-Bedingung binden? und es ist Schwester Q&A.

    – hakre

    5. Dezember 2016 um 11:29 Uhr


Sie können dies auch versuchen (Dokumentation lesen)

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

  • +1 zu dieser Antwort. Die Verwendung von Array-Bindungen wie im obigen Beispiel schützt Sie. Weitere Infos hier forums.laravel.io/viewtopic.php?id=11068

    – Laurenz

    23. September 2013 um 3:03 Uhr


  • Dies beantwortet die Frage nicht, es besagt, dass ich nicht mit Platzhaltern nach der Lösung gesucht habe, sondern nach dem geeigneten Weg, um eine Variable zu maskieren.

    – Dwight

    24. September 2013 um 1:22 Uhr

  • @Dwight, das ist, was die array binding/bound params tut, sicher, entgangen, es konnten keine SQL-Injektionen angewendet werden und nicht nur Platzhalter. Lesen Sie einfach diese Antwort, um sich zu klären.

    – Das Alpha

    24. September 2013 um 1:35 Uhr


  • @Dwight, beachte auch den ersten Kommentar, hat es dich nicht aufgeklärt?

    – Das Alpha

    24. September 2013 um 1:39 Uhr

In zwei Antworten hier, die ich verwende, sind weniger ausführliche Lösungen integriert DB Fassade.

Zunächst Wertzitierung:

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

Zweitens, Identifier-Quoting (Tabellen- und Spaltennamen):

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

Ich habe diese Frage gefunden, als ich in Laravel nach generischem SQL-Escape gesucht habe. Was ich aber eigentlich brauchte, war das Entkommen von Tabellen-/Spaltennamen. Also zum späteren Nachschlagen:

/**
 * 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);
}

  • DB::query()->getGrammar() könnte ein direkterer Ansatz sein. Hält andere Entwickler davon ab, zu viele Fragen zu stellen.

    – Amphetamaschine

    18. Juni 2019 um 15:48 Uhr

Benutzer-Avatar
J. Bruni

Ich benutze das in meinem helpers.php bei Laravel5:

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

Dann kann ich verwenden esc_sql Funktion, bei der ich für rohe SQL-Abfragen pergorm maskieren muss.

  • DB::query()->getGrammar() könnte ein direkterer Ansatz sein. Hält andere Entwickler davon ab, zu viele Fragen zu stellen.

    – Amphetamaschine

    18. Juni 2019 um 15:48 Uhr

Benutzer-Avatar
mpen

Hier ist ein ausführlicheres Beispiel, das zeigt, wie man sowohl Werte als auch Spalten maskiert und Laravels QueryBuilder erweitert:

<?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]);
        });
    }
}

1224280cookie-checkEntgehen Sie rohen SQL-Abfragen in Laravel 4

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy