2012-04-01 7 views
-1

in PHP oft Sie SQL-Abfragen haben, die wie die anderen PHP-Zeichenfolgen enthalten:Beautifier für SQL-Strings in PHP-Code

$sql = "SELECT * 
FROM `mytable` 
". (isset($a) ? $a : "") . " 
LIMIT " . ($page - 1) * 10 . ",10"; 

Wenn Abfragen viel größer dann das sind und mit php gestopft, wird es manchmal schwer zu lesen .

Gibt es Verschönerungen, die PHP mit (My) SQL formatieren können?

+0

Ich habe viel gesehen, viel schlimmer als das. Wie willst du es überhaupt tun? Und was meinst du mit dem Parsen der SQL-Zeichenfolge beim Einfärben ihrer Schlüsselwörter? –

+0

Deshalb wurden Variablen erfunden. Nun, nicht genau, aber sie helfen auch hier. – JJJ

+7

Bitte, um Himmels willen ... bauen Sie Ihre SQL nicht per String concat! Entkomme zumindest den Parametern. Besser: Verwenden Sie PDO mit vorbereiteten Anweisungen. – Malax

Antwort

3

Lassen Sie mich einen anderen Ansatz auf Ihre Frage nehmen:

Wenn Sie SQL-Abfragen haben, die so aussehen, bist du es falsch zu machen.

Prepared statements sind Ihre Freunde. SQL-Injection ist nicht dein Freund. Zu zitieren the PDO documentation:

Prepared Statements sind so nützlich, dass sie das einzige Merkmal, dass PDO auch für Treiber emulieren wird, die sie nicht unterstützen.

Vielleicht denken Sie, Sie in Ordnung sind, und Sie verwenden mysql_real_escape_string() überall Sie müssen (und nicht versehentlich mysql_escape_string() stattdessen verwenden). Vielleicht denken Sie, magic_quotes und stripslashes werden Sie speichern. Vielleicht wirst du Glück haben und es richtig machen. Aber um zu paraphrasieren Ms. Schmich: Wenn ich Ihnen nur einen Tipp für die Zukunft anbieten kann, wäre "gebrauchsfertige Aussagen".

Here is a nice StackOverflow answer illustrating them in more detail und unten ist mein Teilumsatz (ohne was auch immer es ist, den Sie mit $a tun) zur Verwendung von vorbereiteten Anweisungen Ihres Beispiel:

$statement = $dbh->prepare("SELECT * FROM `mytable` LIMIT :offset , 10"); 
$statement->bindValue(":offset", ($page - 1) * 10)); 
$statement->execute(); 

Zugegeben, vielleicht haben Sie einige Legacy-Code geerbt und darum fragst du, deshalb wird meine Position ein bisschen strittig. Ich bin immer noch der Meinung, dass es am besten ist, wenn Sie auf vorbereitete Anweisungen umstrukturieren, sowohl was die Sicherheit/Funktionalität betrifft, als auch, weil sie wahrscheinlich einfacher zu lesen sind, wenn sie möglicherweise ausführlicher sind.

+0

Ich habe eine kleine Frage dazu. Sind die bindenden Werte/Parameter etwas langsamer als in Arrays? (Ich dachte, es ist das gleiche, aber durch Yiis Framework-Dokumentation gehen, sagte, dass die Referenz in execute ist schneller um einen Rand) – itachi

+0

Ich denke, dass das der Fall sein könnte, aber ich wäre unglaublich überrascht zu hören, dass das ist Ihr Engpass aus Profilieren ... –

+0

Lol-Nr. Hatte Benchmark gemacht. Unerheblich. Fast zu nichts. – itachi

1

Versuchen Sie vielleicht, Ihre Werte außerhalb der Abfragezeichenfolge zu ermitteln. Und fügen Sie sie hinzu, nachdem sie Filter-/Validierungsüberprüfungen bestanden haben, die Sie anwenden möchten.

$param = (isset($a) ? $a : ""); 
$param2 = ($page - 1) * 10; 

$sql = "SELECT * FROM mytable " . $param . " LIMIT " . $param2 . ",10"; 
+0

Seien Sie auch vorsichtig, was Sie in diese Zeichenfolge eingeben, stellen Sie sicher, dass sie nicht von etwas stammt, das vom Client kommt (get/post/server usw.). –

+0

geeigneterweise sollte die Variable bereinigen/escape/gefiltert (verschiedene Leute verwenden unterschiedliche Wörter), bevor Sie die Abfrage setzen. Wenn wir Variablen verbieten, welche Quellen vom Client stammen, was nützt dann eine Mainstream-Site? – itachi

+0

Ich werde umformulieren, stellen Sie sicher, dass es nicht direkt vom Client bezogen wird. Und angemessene sanitäre Einrichtungen wurden angewandt. –

0

können Sie Berechnungen außerhalb der Abfrage

$a = isset($a) ? $a : ""; 
$page = ($page - 1) * 10; 

$sql = "SELECT * FROM `mytable` $a LIMIT $page,10"; 
3

Es gibt keine Verschönerungs dass Ihr Code neu strukturieren würde, so dass es einfacher ist, zu lesen. Das ist Ihr Job als Programmierer; einige argumentieren, dass es Haupt Job des Programmierers ist. Also, anstatt hässlichen Code zu schreiben und zu versuchen, den Computer dazu zu bringen, es für Sie aufzuräumen, versuchen Sie, sich an die Gewohnheit zu gewöhnen, lesbaren Code zu schreiben. In diesem Fall gibt es noch mehr Vorteile als die Lesbarkeit (z. B. das Entkommen und Validieren der Variablen).

$conditions = (isset($a) ? $a : ""); 
$lowerLimit = ($page - 1) * 10; 

$sql = "SELECT * 
    FROM `mytable` 
    $conditions 
    LIMIT $lowerLimit, 10"; 
0

Sie könnten versuchen, einige DB-Agenten zu finden, aber in meiner Erfahrung kann ich Ihnen sagen, dass oder es fehlt ihnen an Fähigkeiten, oder sie sind schwer zu daran zu gewöhnen.

Nichtsdestoweniger können Sie versuchen, eine sauberere Abfrage selbst zu machen, indem Sie vars unterscheiden. Sie können sogar einfache Hilfsfunktionen ausführen.

0

Verwenden Sie nach Möglichkeit vorbereitete Anweisungen.

PDO Beispiel:

$PDO = new PDO('host=localhost;dbname=test', 'foo', 'bar'); 

$query = $PDO->prepare(' 
    SELECT 
     * 
    FROM 
     foobar 
    WHERE 
     id = :user_id 
    LIMIT 
     :limit 
'); 

$query->execute(array(
    ':user_id' => $user_id, 
    ':limit' => $limit 
)); 
$query->fetchAll(); 
/*...*/ 

Vorbereitete Anweisungen sind leicht zu pflegen, und Sie können zu entkommen manuelle Zeichenfolge vermeiden.

0

Sie die Art und Weise ändern, könnten Sie Ihren SQL-Code schreiben, um es wie so auf einen Web-basierten beautifier Kopieren/Einfügen zu erleichtern zu

$param = (isset($a) ? $a : ""); 
$param2 = ($page - 1) * 10; 

$sql = " 
SELECT * FROM mytable $param LIMIT $param2,10 
"; 

Dann Sie die mittleren Linie kopieren und einfügen in einen Web-basierten beautifier (see here) und es spuckt

SELECT * 
FROM mytable $param 
LIMIT $param2, 10 

Wenn Sie vim/emacs verwenden, dann diese ganze Sache, indem man auf eine Shell basierte SQL beautifier vereinfacht werden könnte, aber für das Leben von mir kann ich nicht finden .