Προς το περιεχόμενο

Περίεργο πρόβλημα σε php και sql με τη χρήση LIKE '%$var%'


doctorized

Προτεινόμενες αναρτήσεις

Δημοσ. (επεξεργασμένο)

EDITED:

Έχω ένα αρχείο html το οποίο περιέχει 2 div. Στο ένα φορτώνεται ένα μενού (navbar) και στο άλλο φορτώνονται σελίδες με βάση την επιλογή που έγινε στο μενού. Κάποιες σελίδες είναι στατικές/φτιαγμένες από πριν, ενώ κάποιες άλλες φτιάχνονται δυναμικά από ένα αρχείο php το οποίο καλείται και αντλεί δεδομένα από βάση δεδομένων. Υπάρχουν μερικά <select> με βάση τα οποία ο χρήστης ρυθμίζει τι θέλει να δει. Ο βασικός κώδικας του php είναι αυτός:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>

<?php
$servername = "";
$username = "";
$password = "";
$dbname = "";

echo "<p>running</p>";

//var tmp_pedio = parent.document.getElementById("pedio");
//var tmp_institution = window.parent.document.getElementById("institution");
//var tmp_city = window.parent.document.getElementById("city");

//$pedio = " `pedio` = '%" . tmp_pedio.selectedIndex . "%'";
//$instit_type = tmp_institution.selectedIndex;
//$city = tmp_city.selectedIndex;
$pedio = " `pedio` LIKE '%1%'";


echo "<p>Τρέχουσα προβολή: ". tmp_pedio . " , " . $pedio. " , ". $instit_type. " , ". $city. " , ". "</p>";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
$conn->set_charset("utf8");
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

$sql = "SELECT * FROM `clients` WHERE"; . $pedio ;
//$sql = "SELECT * FROM `clients` WHERE `pedio` = '1'";// . $pedio ;
echo $sql;
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    .....
    .....
    // output data of each row
	$i = 1;
    while($row = $result->fetch_assoc()) {
	.....
	.....
	$i++;
    }
	echo "<p>Βρέθηκαν αποτελέσματα.</p>";
} else {
    echo "<p>Δεν βρέθηκαν αποτελέσματα</p>";

}
$conn->close();
?>

</body>
</html>

Οι τελείες αντικατέστησαν κάποια echo τα οποία φτιάχνουν έναν πίνακα ο οποίο μπορεί να περιέχει μέχρι και 450 εγγραφές. Αν τρέξω απλώς την εντολή:

$sql = "SELECT * FROM `clients` WHERE `pedio` = '1'";

τότε εμφανίζεται σωστά ο πίνακας. Αν όμως χρησιμοποιήσω την εντολή:

$sql = "SELECT * FROM `clients` WHERE"; . $pedio ;

και το $pedio περιέχει το υπόλοιπο κομμάτι της εντολής με το = τρέχει πάλι κανονικά. Αν όμως κάνω χρήση του LIKE όπως στον κώδικα από πάνω, τότε ο κώδικας δείχνει να μην τρέχει, δεν εμφανίζεται τίποτα. Διαπίστωσα ότι αν από την εντολή με το LIKE διώξω το δεύτερο % τελείως ή αν μπει κάποιος άλλος χαρακτήρας στη θέση του ο κώδικας τρέχει αλλά η εντολή είναι λάθος και δεν επιστρέφουν αποτελέσματα. Η στήλη pedio στη βάση περιέχει τιμές όπως:
1
2
13
14
1234
το 13 σημαίνει ότι η εγγραφή ανήκει στην 1η και 3η κατηγορία. Εγώ μπορεί να θέλω τις εγγραφές που ανήκουν μόνο στην 2η (ανεξάρτητα αν η εγγραφή ανήκει και σε άλλη κατηγορία) οπότε αναγκαστηκά χρησιμοποιώ "LIKE '%2%' ". To θέμα είναι τι φταιεί και γιατί; Πώς το διορθώνω;

Επίσης, πώς μπορώ να πάρω τις τιμές από τα <select>; Οι εντολές που έχω κάνει σχόλια έχουν σαν αποτέλεσμα να φαίνεται ότι ο κώδικας δεν τρέχει, δεν γίνεται τίποτα. Εννοείται πως τα select έχουν το αντίστοιχο id (<select id="pedio" class=options>) αλλά ούτε το "window.parent.document.getElementById()" μου κάνει ούτε το "document.getElementById()". Τι να χρησιμοποιήσω;

Δοκίμασα εντολές όπως:

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

αλλά δεν πήρα κάποιο αποτέλεσμα.

Επεξ/σία από doctorized
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Απαντ. 41
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

8 λεπτά πριν, elorant είπε

Στο ότι περνάς τιμές κατευθείαν από το query string στην βάση.

Και επιμένω, τι σχέση έχει με το πρόβλημά μου; Είναι ο αρχικός σχεδιασμός και θα αλλάξει, δεν θα περνά τιμή στην κλήση. Ακόμη κι αν πω δοκιμαστικά: $pedio = " `pedio` LIKE '%1%'";  $sql = "SELECT * FROM `clients` WHERE " . $pedio;  πάλι έχω πρόβλημα.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

8 λεπτά πριν, elorant είπε

Δεν έχει καμία σχέση με το πρόβλημα σου. Απλά είναι κακή πρακτική και γι αυτό στο επεσήμανα.

Θα παίρνω τις τιμές απευθείας από τα select που υπάρχουν στην αναζήτηση και θα φτιάχνω την εντολή.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)

Εκτός από το ξεβράκωτο query όμως δεν μας είπες ποιο είναι το πρόβλημα? Δείξει όλο το script, τι περίμενες να πάρεις για αποτέλεσμα και τι έχεις?

 

Αναφορά σε κείμενο

Θα παίρνω τις τιμές απευθείας από τα select που υπάρχουν στην αναζήτηση και θα φτιάχνω την εντολή.

 

Αυτό δεν σώζει κάτι, αν η php δέχεται url params και τα περνάει αμάσητα στο query έχεις πρόβλημα, αν θες ανέβασέ το κάπου να παίξουμε :)

Επεξ/σία από alou
  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

13 λεπτά πριν, alou είπε

Εκτός από το ξεβράκωτο query όμως δεν μας είπες ποιο είναι το πρόβλημα? Δείξει όλο το script, τι περίμενες να πάρεις για αποτέλεσμα και τι έχεις?

Αυτό δεν σώζει κάτι, αν η php δέχεται url params και τα περνάει αμάσητα στο query έχεις πρόβλημα, αν θες ανέβασέ το κάπου να παίξουμε :)

Λέω. Δεν τρέχει ο κώδικας ή τουλάχιστον έτσι δείχνει. Κάνω κλικ στην επιλογή που θα τρέξει το php και δεν συμβαίνει τίποτα ενώ θα έπρεπε να εμφανίσει σελίδα με τα αποτελέσματα. Όταν πάω σπίτι σε κανένα μισάωρο θα ανεβάσω τον κώδικα όπως είναι τώρα.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Α) SOS SOS SOS DO USE PREPARED STATEMENTS: https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php είναι ανάγκη και κόψιμο να διορθώσεις ΠΡΩΤΑ αυτό. Οι καλές πρακτικές μαθαίνονται από νωρίς. Εφόσον το κάνεις ανανέωσε την αρχική ερώτηση.

Β) Για να δεις τι παίζει κάνε debug με το εργαλείο Xdebug. https://stackoverflow.com/questions/29847872/install-xdebug-for-lamp

C) Ρύθμισε το PDO σαν $dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); και όπου εκτελείς κάνε try catch.

D) Τραβάς πολλά από την βάση? Μήπως πρέπει να κάνεις pagination?

Ε) Το $pedio πριν κάνεις το query τι τιμές παίρνει;

 

έλος μήπως σε βολέυει να χρησιμοποιήσει ΑΥΤΟ: https://github.com/nilportugues/php-sql-query-builder

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

58 λεπτά πριν, PC_MAGAS είπε

Α) SOS SOS SOS DO USE PREPARED STATEMENTS: https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php είναι ανάγκη και κόψιμο να διορθώσεις ΠΡΩΤΑ αυτό. Οι καλές πρακτικές μαθαίνονται από νωρίς. Εφόσον το κάνεις ανανέωσε την αρχική ερώτηση.

Β) Για να δεις τι παίζει κάνε debug με το εργαλείο Xdebug. https://stackoverflow.com/questions/29847872/install-xdebug-for-lamp

C) Ρύθμισε το PDO σαν $dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); και όπου εκτελείς κάνε try catch.

D) Τραβάς πολλά από την βάση? Μήπως πρέπει να κάνεις pagination?

Ε) Το $pedio πριν κάνεις το query τι τιμές παίρνει;

έλος μήπως σε βολέυει να χρησιμοποιήσει ΑΥΤΟ: https://github.com/nilportugues/php-sql-query-builder

Α) όλα από την αρχή.

D) Maximum 450 εγγραφές αλλά σε καμία περίπτωση δεν θέλουμε pagination.

Ε) το $pedio θα πρέπει να έχει μία από τις εξής 4 τιμές:

$pedio = " LIKE '%1%'";

$pedio = " LIKE '%2%'";

$pedio = " LIKE '%3%'";

$pedio = " LIKE '%4%'";

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Άρα όσο αφορά το $pedio πρέπει να βάλεις if/switch και να ελέγχεις τις προυποθέσεις για να ισχύει μιά από τις παρακάτω τιμές.

Στις 30/1/2019 στις 12:06 ΠΜ, doctorized είπε

$pedio = " LIKE '%1%'";

$pedio = " LIKE '%2%'";

$pedio = " LIKE '%3%'";

$pedio = " LIKE '%4%'";

Κατ' αρχάς ένα xdebug λύνει τέτοιες υποθέσεις πρέπει να δεις εκεί που σχηματίζει το query τι τιμή λαμβάνει η μεταβλητή $pedio.  Εναλλακτικά ένα echo παίζει  ένα καίγεσαι αλλά οδηγεί μακροπρόθεσμα σε οδηγήσει σε προβλήματα ξόδεψε 1-2 ώρες να παίζεις/στήσεις με Xdebug σώζει ζωές.

Ακόμη δε τρέξε χεράτα τα queriesστην βάση na deiw e;an pa;izei svst;a.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

$sql = "SELECT * FROM `clients` WHERE"; . $pedio ;
//$sql = "SELECT * FROM `clients` WHERE `pedio` = '1'";// . $pedio ;

Δες το semicolon που έχεις στο query σου.

 

echo "<p>Τρέχουσα προβολή: ". tmp_pedio . " , " . $pedio. " , ". $instit_type. " , ". $city. " , ". "</p>";

το tmp_pedio είναι σταθερά ή μεταβλητή; Αν είναι μεταβλητή ίσως πρέπει να του βάλεις δολάριο;

Έχω πετύχει server που δεν αφήνει να έχεις μια βάση default και να πρέπει να την βάζεις πάντα στο query. πχ:

$sql = "SELECT * FROM `$dbname`.`clients` WHERE" . $pedio ;

 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)
22 λεπτά πριν, elvizakos είπε

$sql = "SELECT * FROM `clients` WHERE"; . $pedio ;
//$sql = "SELECT * FROM `clients` WHERE `pedio` = '1'";// . $pedio ;

Δες το semicolon που έχεις στο query σου.


echo "<p>Τρέχουσα προβολή: ". tmp_pedio . " , " . $pedio. " , ". $instit_type. " , ". $city. " , ". "</p>";

το tmp_pedio είναι σταθερά ή μεταβλητή; Αν είναι μεταβλητή ίσως πρέπει να του βάλεις δολάριο;

Έχω πετύχει server που δεν αφήνει να έχεις μια βάση default και να πρέπει να την βάζεις πάντα στο query. πχ:


$sql = "SELECT * FROM `$dbname`.`clients` WHERE" . $pedio ;

Έβαλα το tmp_pedio για να πάρει προσωρινά μία τιμή, δεν την αλλάζω μετά. Ακόμη κι αν τα διώξω όλα και πω απευθείας "SELECT * FROM `clients` WHERE pedio LIKE '%1%'" πάλι δεν τρέχει. Από την άλλη, η εντολή αυτή τρέχει κανονικά στον πίνακα ελέγχου που διαχειρίζεται τη βάση. Υποψιάζομαι ότι κάποια λ@λ@κί@ έχουν κάνει οι administrators. Έχω στείλει μήνυμα αλλά δεν πήρα απάντηση. Θα τους τηλεφωνήσω τη Δευτέρα. Μπορώ να βάλω το όνομα της βάσης απευθείας, δηλαδή να πω (έστω test το όνομα της βάσης):

$sql = "SELECT * FROM `test`.`clients` WHERE" ...

ή πρέπει οπωσδήποτε να βάλω το `$dbname`;

 

Επεξ/σία από doctorized
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μπορείς και με τους δυο τρόπους. Λογικά όμως δεν είναι αυτό το πρόβλημα.

Τώρα, στην ερώτηση σου λες:

Αναφορά σε κείμενο

Αν τρέξω απλώς την εντολή:


$sql = "SELECT * FROM `clients` WHERE `pedio` = '1'";

τότε εμφανίζεται σωστά ο πίνακας

αλλά το "SELECT * FROM `clients` WHERE pedio LIKE '%1%'"  δεν σου δουλεύει, οπότε αν το πρόβλημα εδώ δεν είναι που δεν έχεις βάλει `` στο pedio τότε για κάποιο λόγο υπάρχει θέμα με το LIKE (το οποίο και είναι όντως περίεργο)...

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα

  • Δημιουργία νέου...