[PHP]Problem mit Wertübergabe per urlencode in URL

padimi

LoseLover
ID: 310552
L
8 April 2008
52
2
Hallo zusammen.
Also es geht um eine normale Datenbankabfrage durch eine Select Anweisung in welcher aber durch eine Variabel unterschiedliche Wert eingesetzt werden sollen.
Der jeweilige Wert der Variabel soll ihr nun in einer URL zugewiesen werden.
Nun zu meinem Problem

SO FUNKTIONIERT ES:


PHP:
$searcher = "'a%' OR headline LIKE 'ä%'";
    // --------------------------
    if (isset($searcher)) {
        $sql1 = "SELECT * FROM weblog WHERE headline LIKE" . $searcher;
        $sql2 = "SELECT * FROM weblog WHERE headline LIKE" . $searcher . "ORDER BY id DESC LIMIT $start, $step";

Der Wert der Variabel sollte aber durch die URL zugewiesen werden und das wollte ich mit "urlencode" machen,
ABER DASS FUNKTIONIERT NICHT:

PHP:
<li><a href="www.blabla/index2.php?searcher=<?php echo urlencode("'a%' OR headline LIKE 'ä%'");
?>">A</a></li>
     // --------------------------
    if (isset($searcher)) {
        $sql1 = "SELECT * FROM weblog WHERE headline LIKE" . $searcher;
        $sql2 = "SELECT * FROM weblog WHERE headline LIKE" . $searcher . "ORDER BY id DESC LIMIT $start, $step";

Kann mir jemand Hinweise geben warum das nicht funktioniert oder mir weiterhelfen, ich hänge da jetzt schon ewig dran und hab schon mehrere unterschiedliche Varianten ausprobiert, da ich mal schwer davon ausgehe das das irgendwie mit den doppelten und einfachen Anführungszeichen zu tun hat.
 
1. Informier dich mal über register_globals.

2. Was du vor hast, ist aber ganz ganz böse. Usereingabe direkt als Datenbankabfrage wird ziemlich schnell in die Hose gehen.
 
Danke erstmal für deine schnelle Antwort.

Bin PHP Anfänger, aber ich probier mal zu verstehen wie du das meinst.
1.
Meinst du das es sowieso nicht so funktionieren würde wenn register Globals auf off sind?
Hab in der PHPINFO gesehen das bei mir Register Globals im Local Value auf On sind und im Master Value auf Off.
Heißt ja dann sozusagen das diese auf dem Server deaktiviert sind, in meinem Webspace Verzeichniss jedoch erlaubt?
Um mir also einen zumindest halbwegs akzeptabelen Programmierstil anzueignen sollte ich diese also auf jeden Fall deaktivieren?
Ist es sinnvoller meinen Hoster deshalb anzuschreiben oder reicht es über htaccess?
2.
Das "in die Hose gehen" beziehst du darauf das jeder der die Seite betritt dann einfach selber über die URL die Suchmaske ändern könnte oder wie?


Sorry für die vielen Fragen, hab mal noch einen Threat aufgemacht in dem ich Jemanden suche der mir für ein Paar Lose in Zukunft immer mal schnell helfen kann.
Wer interesse hat kann dort gerne posten.
https://www.klamm.de/forum/showthread.php?p=3782686#post3782686
Gruss Padimi
 
Meinst du das es sowieso nicht so funktionieren würde wenn register Globals auf off sind?
Richtig. Übergebene Variablen wären in diesem Fall nicht sofort als $varname auswertbar, sondern über $_POST['varname'] oder ähnlich je nachdem woher sie kommen.

Hab in der PHPINFO gesehen das bei mir Register Globals im Local Value auf On sind und im Master Value auf Off.
Heißt ja dann sozusagen das diese auf dem Server deaktiviert sind, in meinem Webspace Verzeichniss jedoch erlaubt?
Ja.

Um mir also einen zumindest halbwegs akzeptabelen Programmierstil anzueignen sollte ich diese also auf jeden Fall deaktivieren?
Genau, du solltest register_globals deaktivieren. Erstens um die Scripte, die bei dir laufen sicherer zu machen und zweitens - wie du selber schreibst - dir das gleich sinnvoll an zu gewöhnen.

Ist es sinnvoller meinen Hoster deshalb anzuschreiben oder reicht es über htaccess?
Im Normalfall sollte es über die .htaccess gehen. Wenn nicht, dann halt doch über den Hoster.

Das "in die Hose gehen" beziehst du darauf das jeder der die Seite betritt dann einfach selber über die URL die Suchmaske ändern könnte oder wie?
Nicht nur die Suchmaske ändern, sondern auch schädlichen MySQL-Code einschleußen und damit entweder Daten aus der Datenbank zu lesen, die ihn nichts angehen oder Daten in die Datenbank schreiben, die da nicht sein sollen. Auf beiden Wegen könnte viel Schaden angerichtet werden.

Sorry für die vielen Fragen, ...
Dazu ist ein Forum doch da. ;)
 
So, ich habe nochmal eine Frage.
Wie schon erwähnt geht es darum das ich ein Menü (das ganze Alphabet) habe und auf klick auf den jeweiligen Buchstaben sollen dann die Datenbankeinträge ausgelesen werden die mit dem jeweiligen Buchstaben beginnen.
Ich habe mir nun überlegt das ich anstatt der Möglichkeit die ich oben benutzt habe beim linkaufruf einfach blos direkt den Buchstaben übergebe und in einem switch, case konstrukt dann das Suchmuster übergebe, in etwa in folgender Form:
PHP:
<li><a href="https://www.blabla/index.php?search=a">A</a></li>

$search = $_POST[search];

switch $search {
case a:
    $searcher = "'a%' OR headline LIKE 'ä%'";
    break;
case b:
    $searcher = "'b%'";
    break;
case c:
    $searcher = "'c%'";
    break;
case d:
    $searcher = "'d%'";
    break;
case e:
    $searcher = "'e%'";
    break;
case f:
    $searcher = "'f%'";
    break;
usw. 
usw.    
       }
  $sql1 = "SELECT * FROM weblog WHERE headline LIKE" . $searcher; 
    $sql2 = "SELECT * FROM weblog WHERE headline LIKE" . $searcher . "ORDER BY id DESC LIMIT $start, $step";

Somit wäre doch dann die Sicherheit gewährleistet wenn ich die Register globals auf off setze oder?
Zum zweiten wollte ich nochmal fragen ob es eventuell eine bessere Methode gibt das umzusetzen da ja sonst bei jeder Abfrage immer erst das komplette konstrukt durchlaufen wird wenn jemand z.b. die Einträge aufruft die mit x, oder z bzw. einen der letzten Buchstaben anfängt und das ja dann auch ganz schön viel Serverressourcen frisst, oder?
Gruss Padimi
 
Zuletzt bearbeitet:
Du könntest statt dem switch() auch ne for Schleife nutzen:

PHP:
<?php
$searcher = $_GET['search'];
$search_start = "a";
for($i=1;$i<=26;$i++)
{
    if($searcher == $search_start)
    {
        echo "Treffer: ".$search_start;
        $searcher = $search_start."%";
    }
    $search_start++;
}
echo '<br>'.$searcher;
?>

Kannst du ja mal testen. Ich weiß nicht ob diese Lösung schneller arbeitet als deine, aber Sie ist zumindest kürzer. Allerdings wären das in diesem Beispiel nur die Buchstaben a-z, also Ä und so weiter fehlt, das müsste man noch ergänzen.
Aber ansonsten funktioniert es soweit.

Grüße
 
PHP:
<?php
$searcher = $_GET['search'];
$search_start = "a";
for($i=1;$i<=26;$i++)
{
    if($searcher == $search_start)
    {
        echo "Treffer: ".$search_start;
        $searcher = $search_start."%";
    }
    $search_start++;
}
echo '<br>'.$searcher;
?>

[Welchen Sinn hat dieser Code? $search_start ist zunächst ein String mit dem Inhalt "a". Sollte $searcher nicht gleich "a" sein wird der String um 1 erhöht, was eine E_NOTICE (oder E_WARNING?) zur Folge hat.] (Edit: Strings können doch inkrementiert werden).

Ich würde folgende Lösung vorschlagen:

PHP:
<?php
    $headline_start = isset($_GET['searcher']) ? (string) stripslashes($_GET['searcher']) : ''; // falls magic_quotes zugeschlagen haben
    
    if(!empty($headline_start)) {
        // nehme nur den ersten Buchstaben
        $search = (strlen($headline_start) > 1) ? $headline_start[0] : $headline_start;
        // Query zusammenbasteln -> deine Aufgabe
    }
       
?>

Greetz

paddya
 
Zuletzt bearbeitet:
Welchen Sinn hat dieser Code? $search_start ist zunächst ein String mit dem Inhalt "a". Sollte $searcher nicht gleich "a" sein wird der String um 1 erhöht, was eine E_NOTICE (oder E_WARNING?) zur Folge hat.

Also bei mir funktioniert es ohne Fehlermeldung. Der Sinn ist, dass der Buchstabe a hochgezählt wird bis zum Buchstaben z.
Glaube auch selber nicht, dass es sauberes PHP ist.

Hast du das denn mal getestet bei dir?
 
Also danke erstmal für eure Antworten und Ideen.
Werde es mal in Ruhe ausprobieren und durchtesten.

Edit:
Was haltet ihr von
Switch Case für a und ä, o und ö, und u und ü und dann in der default Anweisung
$searcher = "'".$search."%'";
Das dürfte das ganze ja dann relativ klein halten?
 
Zuletzt bearbeitet:
Danke für eure Hilfe, ich habs jetzt hinbekommen.
PHP:
// hier wird abgefragt ob $searcher vorhanden ist und wenn ja wird $searcher als suchmuster benutzt
    $search = $_GET['search'];
    if (isset($search))//falls $search gesetzt ist
    {
    switch ($search) { //$search fallunterscheidung
        case a:
            $searcher = "'a%' OR headline LIKE 'ä%'";
            break;
        case o:
            $searcher = "'o%' OR headline LIKE 'ö%'";
            break;
        case u:
            $searcher = "'u%' OR headline LIKE 'ü%'";
            break;
        default:
             $searcher = "'" . $search . "%'";
             break;
             }//schließende klammer if isset $search
             }  //schließende Klammer switch
            else {
                $sql1 = "SELECT * FROM weblog";
                $sql2 = "SELECT * FROM weblog ORDER BY id DESC LIMIT $start, $step";
            } //schließende Klammer else
    $sql1 = "SELECT * FROM weblog WHERE headline LIKE" . $searcher; //Umlaute bei sql abfrage nicht als asci sondern richtig
    $sql2 = "SELECT * FROM weblog WHERE headline LIKE" . $searcher . "ORDER BY id DESC LIMIT $start, $step";
 
Also bei mir funktioniert es ohne Fehlermeldung. Der Sinn ist, dass der Buchstabe a hochgezählt wird bis zum Buchstaben z.
Glaube auch selber nicht, dass es sauberes PHP ist.

Hast du das denn mal getestet bei dir?

Tatsache. Es funktioniert. Wobei die Schleife trotzdem unnötig ist ;)

Greetz

paddya
 
Wie wär es dann mit dem klassischen Ansatz einer Whitelist:

- Mal auf die Schnelle ohne die Syntax kontrolliert zu haben -
Zunächst ein Array mit allen erlaubten Anfangszeichen, z.B. per range() erstellt:

PHP:
$sollzeichen = range('a','z');

Dann testen, ob das übergebene Zeichen im Array ist

PHP:
if(in_array($_GET['search'],$sollzeichen))
{
$sql = "SELECT * FROM weblog WHERE headline LIKE '".$_GET['search']."%'";
}
else
{
$sql = "SELECT * FROM weblog "; //oder was auch immer
}

Und dann die Datenbankabfrage.

Wieso hast du eigentlich Probleme mit den Umlauten?
 
Sorry, hab deine Antwort jetzt erst gesehen.
Also habs ja jetze hinbekommen.
Ich hab ja keine Probleme mit den Umlauten blos ich wollte halt bei der Abfrage von a, o, und u auch die Abfrage des dazugehöhrigen Umlauts mit drinne haben.
Gruss Padimi
 
Die Umlaute müssten doch auch ohne Sonderbehandlung dabei sein:
Code:
mysql> SELECT 'äää' LIKE 'a%';
+--------------------+
| 'äää' LIKE 'a%' |
+--------------------+
|                  1 | 
+--------------------+
 
Die Umlaute müssten doch auch ohne Sonderbehandlung dabei sein:
Code:
mysql> SELECT 'äää' LIKE 'a%';
+--------------------+
| 'äää' LIKE 'a%' |
+--------------------+
|                  1 | 
+--------------------+
Sorry, aber bin wie schon erwähnt noch relativer PHP Grünschnabel und kann deinem Codebeispiel jetzt nicht entnehmen wie du das meinst.
Schreibe doch bitte nochmal etwas ausführlicher worauf du hinaus willst
Gruss Padimi
 
Das Beispiel zeigt, dass der String 'äää' von dem LIKE-Suchmuster 'a%' erkannt wird, da das Ergebnis 1 (=wahr) ist.

Ob das nun nur bei entsprechendem Collate der Fall ist, entzieht sich meiner Kenntnis, genauso wie ich leider den Passus für die oben beschriebene Funktionsweise im Handbuch nicht finde.