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

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


doctorized

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

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

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

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

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

Ναι. Με " = '1' " τρέχει σωστά.

Με " = '%1%' " τρέχει αλλά χωρίς αποτελέσματα λόγω λανθασμένης εντολής.

Με " LIKE '%1' " τρέχει. Αν θυμάμαι καλά χωρίς αποτελέσματα.

Με " LIKE '%1%' " δεν τρέχει. Η εντολή αυτή τρέχει κανονικά στον πίνακα ελέγχου του παρόχου αλλά δεν τρέχει στο php.

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

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

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

7 λεπτά πριν, j2k είπε

Αυτος ο κωδικας και εγω που εχω ξεχασει τον προγραμματισμο που ηξερα βλεπω οτι ειναι αθλιος.

Ολα λαθος.

Γιατί άθλιος; Γράψε τον εσύ σωστά.

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

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

Ξεκινα απο τα βασικα πχ πως μπαινεις σε php και βγαινεις απο php

αυτο τι νοημα εχει ?

echo "<p>Δεν βρέθηκαν αποτελέσματα</p>";

ΔΕΝ θελει echo

?>
<p>Δεν βρέθηκαν αποτελέσματα</p>
<?php

Τωρα για για τα concatenated strings σε queries σου τα ειπανε..

Γενικα ειναι ολα λαθος δεν εχει δομη ιεραρχια αρχιτεκτονικη τιποτα...

Ξεκινα απο τα βασικα πρωτα.

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

16 λεπτά πριν, j2k είπε

Ξεκινα απο τα βασικα πχ πως μπαινεις σε php και βγαινεις απο php

αυτο τι νοημα εχει ?


echo "<p>Δεν βρέθηκαν αποτελέσματα</p>";

ΔΕΝ θελει echo


?>
<p>Δεν βρέθηκαν αποτελέσματα</p>
<?php

Τωρα για για τα concatenated strings σε queries σου τα ειπανε..

Γενικα ειναι ολα λαθος δεν εχει δομη ιεραρχια αρχιτεκτονικη τιποτα...

Ξεκινα απο τα βασικα πρωτα.

Βοήθησέ με να καταλάβω. Σε ποια δομή, ιεραρχία, αρχιτεκτονική αναφέρεσαι; Πετάς απλώς ένα "λάθος". Εξήγησέ το μου λεπτομερώς να καταλάβω το λάθος.

Από την άλλη, είναι τόσο τραγικό το echo; Για ποιο λόγο να κλείσω τον php κώδικα με ?> να γράψω μία γραμμή και να τον ανοίξω πάλι; Τόσο τραγικό είναι να μπει μέσα στον php κώδικα αυτή η γραμμή; Από το να υποτιμάς κάποιον με τα λόγια σου, εξηγήσου λεπτομερώς. Δεν είμαι php προγραμματιστής οπότε εξήγησέ μου.

Επίσης, λες ότι οι άλλοι μου "τα είπανε" για τα concatenated strings. Τι ακριβώς μου είπαν; Στην ουσία δεν μου είπαν τίποτα καινούριο.

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

6 λεπτά πριν, j2k είπε

Ουτε εγω ειμαι προγραμματιστης..

Ψαξε για mvc design pattern για αρχη για prepared statements/pdo και γενικα για php.

Τι το θέλω το mvc design pattern; Να εξηγήσω λίγο κάποια πράγματα γιατί μάλλον όλοι κάνετε κάποιο λάθος. Πρόκειται για ένα σύστημα ενημέρωσης το οποίο το μόνο που κάνει είναι να τραβάει κάποια στοιχεία από μία βάση και να τα εμφανίζει σε έναν πίνακα. Δεν γράφουμε στη βάση, μόνο διαβάζουμε. Δεν υπάρχουν χρήστες, δεν γίνεται login γιατί η χρήση είναι ελεύθερη για όλους άρα δεν βλέπω το λόγο να πάει κάποιος και να κάνει επίθεση (sql injection). Άρα τι τα θέλω τα prepared statements;

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

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

Ακόμη επεκτείνοντας το @andreaszks λέει δε με ένα whitelist rule μπορεί να παίξει εάν πεδίο δεν είναι 1,2,3,4 τότε απόρριψε.

$pedio=intval($_GET['pedio');
if(!in_array($pedio,[1,2,3,4])) die();

// Den exei sql injection άνουμε Sanitize poio pano
$sql="SELECT * FROM `clients` WHERE `pedio` LIKE '%".$pedio."%'";

//Rest code

Ακόμη δε στο Approach σου δοκίμασε να παίξεις με binary πχ (0b binary).

Κατηγορία 1: 0b10000

Κατηγορία 2: 0b01000

κλπ κλπ

Δλδ. μια n-sized μπιτοσειρά που είναι 1 το bit στην θέση την οποία η κατηγορία ανήκει. Μετά θα πρέπει να χρηματίζεις μια  check value η οποία θα είναι ένα integer που θα το bit του έχει 1 στην θέση την οποία θες να ελέγξεις εάν είναι. Μετά κάνεις μια δυαδική συνάρτηση μέσω πίνακα αληθείας https://www.allaboutcircuits.com/textbook/digital/chpt-7/converting-truth-tables-boolean-expressions/ και την αναπτύσσεις σαν mysql function η οποία θα επιστρέφει TRUE εάν η τιμή ενός πεδίου έχει 1 στην θέση την οποία έθεσες 1 στην check value https://dev.mysql.com/doc/refman/5.7/en/create-procedure.html , https://dev.mysql.com/doc/refman/5.7/en/bit-functions.html.

Εναλλακτικά μπορείς να ορίζεις τις κατηγορίες σε έναν τρίτο πίνακα με ξένο κλειδί το id του πίνακα clients και έναν integer που να δηλώνει την κατηγορία. Μετά είναι εύκολο να κάνεις ένα Join και να ελέγχεις εάν το πεδίο την κατηγορίας είναι σε μία από τις τιμές που όρισες εάν ακολουθήσεις αυτήν την προσέγγιση τότε δες και αυτό https://stackoverflow.com/a/23641033. Αυτή η προσέγγιση κατ εμέ είναι ευκολότερη και ποιο συντηρίσιμη  με το κόστος να έχεις μια μεγαλύτερη βάση σε σύγκριση με την προηγούμενη προσέγγιση.

4 ώρες πριν, doctorized είπε

Τι το θέλω το mvc design pattern;

Δεν υπάρχουν χρήστες, δεν γίνεται login γιατί η χρήση είναι ελεύθερη για όλους άρα δεν βλέπω το λόγο να πάει κάποιος και να κάνει επίθεση (sql injection).

Για πολλούς λόγους θες MVC:

  1. Εάν το boss ή ο καθηγητής σου αύριο μεθαύριο πει Α δεν μου αρέσει αυτό το θέλω έτσι φτου ξανά να εντοπίζεις και να αλλάζεις τα αισθητικά κομμάτια όταν είναι αχταρμά με την λογική σου.
  2. Σου επιτρέπει να έχεις χωρισμένα το κομμάτι που σου εμφανίζει την πληροφορία και το κομμάτι που σου τραβά αυτήν. Σε συνδυασμό με Depedency Injection πχ. Symfony είναι λουκουμάκι.
  3. Επιτρέπει στον άλλο τον φουκαριάρη developer να πειράζει την εμφάνιση χωρίς να σου διαλύει τελείως την λογική, δλδ καλύτερα να χωρίζεις τα χωράφια και ποιος θα "καλλιεργεί" σε αυτά πχ. Ο frontend θα πειράζει Html/css και ελάχιστα php ενώ εσύ θα κάνεις παπάδες ανενόχλητος στο πως θα τα φέρεις από την βάση.
  4. Ακόμα και το αντίστροφο φαντάσου ότι οι πελάτες ανήκουν σε 1.000.000 κατηγορίες και η MYSQL πει φτου ΔΕΝ ΑΝΤΕΧΩ και πάς σεάλλη τεχνολογία πχ. elastic search με MVC θα αλλάζεις μόνο το κομματάκι που φέρνει τα data και θα το αναπτύξεις σε λιγότερο χρόνο. Έτσι το boss θα είναι ποιο ευχαριστημένος και θα σε απασχολείτε στο να αναπτύσσεις το επόμενο "γαμάτο" feature.

Και τώρα ποιος θα κάνει SQL injection χμμμ αυτός που έχει να πληρωθεί κάτι μήνες και θα θέλει να πάρει το μισθό του δίνοντας access σε τρίτον επί πληρωμής, ο junior script kiddie που θα θέλει να "παίξει", με αποτέλεσμα να χάνει η εταιρεία με πόρους που ούτε το φαντάζεσαι.  Παρόλο που είναι μόνο-ανάγνωση σύστημα θα πρέπει να μεριμνήσεις να είναι αποκλειστικά μόνο-ανάγνωση και όχι να έχει το "feature" ο άλλος να μπορεί να γράφει δίνοντας το κατάλληλο-που-δεν-έχεις-προβλέψει input.

 

Και στην τελική βάλτο και άστο δεν χάλασε κανέναν ένα ασφαλέστερο σύστημα γιατί τα συστήματα ξέρεις αλλάζουν εξελίσσονται ακόμα και τα παρατημένα κάποιος άλλος θα χρειαστεί να γράψει κώδικα σε αυτό σε κάποιο μακρύ χρονικό διάστημα και στην τελική πληρώνεσαι ή βαθμολογείσαι (Εάν είναι εργασία Παν/μιου, ΤΕΙ, ΙΕΚ) για να δώσεις το καλύτερο. Στο input MHN εμπιστεύεσαι ούτε εσένα.

 

Ακόμη δε δες και κάνα framework ακόμα σε σε trivial task καλύτερα είναι να πας σε ένα framework γνωστό και δημοφιλές που έχει καλυμμένα αρκετά κομμάτια ασφαλείας κλπ κλπ. Σου συστήνω Symfony ή Laravel. Προσωπικά παίζω symfony λόγο της σταθερότητας αλλά και το modulartiy που έχει.

 

Ακόμα και κώδικας παραγωγής να είναι σε σκατοεταιρεία να είναι το σύστημα που αναπτύσσεις, δεν σημαίνει ότι και εσύ θα είσαι προγραμματιστής του επιπέδου που θα είναι η εταιρεία που εργάζεσαι. Και σκέψου πως εάν αύριο μεθαύριο σου έρθει μια καλύτερη προοπτική θα πρέπει να δείξεις ότι είσαι ο καλύτερος για τα λεφτά που θα σου δώσουν, το prepared statement σε κάνει καλύτερο και ποιον ανταγωνιστικό σαν developer με το να σε φέρνει στα ίσα με τους συναδέλφους.

 

Πίστεψέ με σε spoilαρω αυτήν την στιγμή βασιζόμενος σε πραγματικό προσωπικό πόνο. Σου τα λέει άτομο που στο stackoverflow είναι top 6% αυτήν την στιγμή και όχι ο μπακάλης της γειτονιάς σου.

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

Δημοσ. (επεξεργασμένο)
2 ώρες πριν, PC_MAGAS είπε

Πίστεψέ με σε spoilαρω αυτήν την στιγμή βασιζόμενος σε πραγματικό προσωπικό πόνο. Σου τα λέει άτομο που στο stackoverflow είναι top 6% αυτήν την στιγμή και όχι ο μπακάλης της γειτονιάς σου.

Ουάου!

Η αλήθεια είναι ότι έβαλα σήμερα κάποιους ελέγχους. Για παράδειγμα:

if (isset($_GET['pedio'])){
	$tmp_pedio = $_GET['pedio'];
	if (ctype_digit($tmp_pedio)) {//check if we have digits only
		if (($tmp_pedio > 0) && ($tmp_pedio < 5)){//we need numbers 1-4 only
			$pedio = " `pedio` = '" . $tmp_pedio . "'";
			$count = 1;
		}
	}else{
		exit("Το πεδίο πρέπει να είναι αριθμός.");		
	}
}
                                                      
if (isset ($_GET['city'])){
	$tmp_city = $_GET['city'];
	if (!preg_match('/^[A-Z\d\D]+$/i', $tmp_city)) {//check if we have greek letters only
		if ($count == 1){
			$city = " AND";
		}
		$city .= " `city` = '" . $tmp_city . "'";
		$count = 1;
	}else{
		exit("Η πόλη πρέπει να περιέχει μόνο ελληνικούς χαρακτήρες.");	
	}
}
                                                      

Η $count μπήκε για να ελέγξω αν έχουν δωθεί παράμετροι άρα αξίζει να προχωρήσουμε ή όχι. Δεν ασχολούμαι ακόμη με το LIKE για να δω τι θα μου πει και ο πάροχος τη Δευτέρα. Θα δοκιμάσω αυτά που προτείνεις. Σε περίπτωση που κάτι πάει στραβά, θέλω να εμφανίζεται ένα ωραίο message box που έχω βρει σε JavaScript. Ο κώδικας για την κλήση:

<script src="alert/sweetalert-dev.js"></script>
  <link rel="stylesheet" href="alert/sweetalert.css">
<script type="text/javascript">
function JSalert(){
	swal({   title: "Δεν υπάρχουν στοιχεία που να ικανοποιούν τα κριτήρια που θέσατε.",   
    text: "",   
    type: "warning",   
    showCancelButton: false,   
    confirmButtonColor: "#DD6B55",   
    confirmButtonText: "OK",   
    closeOnConfirm: true,   
    closeOnCancel: true });
}
</script>

Αυτά τα έχω βάλει στην αρχή του php μέσα στον header, δηλαδή:

<html>
<head>
<meta charset="UTF-8">
<script src="alert/sweetalert-dev.js"></script>
<link rel="stylesheet" href="alert/sweetalert.css">
<script type="text/javascript">
function JSalert(){
	swal({   title: "Δεν υπάρχουν στοιχεία που να ικανοποιούν τα κριτήρια που θέσατε.",   
    text: "",   
    type: "warning",   
    showCancelButton: false,   
    confirmButtonColor: "#DD6B55",   
    confirmButtonText: "OK",   
    closeOnConfirm: true,   
    closeOnCancel: true });
}
</script>
</head>
<body>

<?php
....
?>

Δεν έχω καταλάβει αν είναι σωστό να έχω <html>, <head> και <body> μέσα στο php αρχείο αλλά δεν διαμαρτύρεται. Προσπάθησα να καλέσω τη function με:

echo '<script type="text/javascript"> JSalert(); </script>';

όπως είδα πολλούς να μαρκάρουν σαν λύση αλλά δεν εμφανίζεται τίποτα. Ακόμη και με απλό alert() που δοκίμασα δεν εμφανίζεται τίποτα, μάλλον ο browser (Firefox και Chrome) για κάποιο λόγο δεν την τρέχει.

Σε ευχαριστώ πολύ για τον ευγενικό και πάνω απ' όλα αδελφικό τρόπο που μου μίλησες. Ειλικρινά το εκτιμώ. Να είσαι καλά.

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

Άρα παίζει να μην έχεις κάνει σωστό HMTL formatting.

Λοιπόν με CTRL+U  στον browser σου δες όλο τον HMTL κώδικα. Στον html κώδικά σου πρέπει ΠΑΝΤΑ να τον ξεκινάς με <!doctype html> μετά στο head μπορείς να βάζεις <meta charset="UTF-8"/> για να σου εμφανίζει καλά όλους τους χαρακτήρες.

ΜΗΝ ξεχνάς να παίζεις με prepared statements ακόμα τα αποτελέσματα από την βάση, να τα γδύνεις από html formatting (ένας να βάλει javascript στην είσοδό σου την έβαψες) εάν θες μερικό Html formating δοκίμασε την βιβλιοθήκη Htmlpurifier (google it) που θα την εγκαταστήσεις μέσω εργαλείου composer (Και ΝΑΙ είναι στάνταρντ εργαλείο για βιβλιοθήκες).

Όσο αφορά το LIKE έχεις τοπικά μια βάση να πάρεις ένα dump από την απομακρυσμένη να την βάλεις τοπικά να δεις ότι παίζει;

Ακόμη δε δοκίμασε να το αλλάξεις με JOIN πρώτα όπως σου είπα πάνω, και γράψε ένα σκριπτάκι που θα κάνει την αλλαγή αυτή στο σχήμα της βάσης, το script μπορεί να συνδέετε ΚΑΙ στην απομακρυσμένη βάση να κάνει τις αλλαγές εφόσον έχεις βάλει τα σωστά credentials εναλλακτικά βάλτο στον σέρβερ προσωρινά μέσω ftp τρέξτο και μετά σβήστο. Παρόμοιες τακτικές με αυτοματοποιημένα εργαλεία γίνονται και σε ποιο μεγάλα project και αυτά τα script ονομάζονται migration scripts.


Τέλος ΧΩΡΙΣΕ την λογική σου από το πως δείχνεις τα δεδομένα σου για αρχή παίξε με ένα microframework πχ flight (google it) και Twig για το view σου. Ότι είναι για Πάρε δώσε με Db κάντο σε μια κλάση και δώσε το στιγμιότυπο του PDO σαν παράμετρο στον κονστράκτορα αυτής.

Με τις συμβουλές μου θα έχεις εφαρμόσει τις ακόλουθες τεχνικές:

  • MVC
  • Depedency Injection
  • Migration Scripts
  • Twig

Που το μόνο που σου μένει εάν ακολουθήσεις τις οδηγίες μου και ψάξεις τι είναι το το καθένα και ποια τεχνική που σου είπα είναι τι. Άμα να τα εφαρμόζεις (ίσως μαθαίνοντας και ένα δημοφιλές framework πχ. Symfony, Laravel) θα είσαι σε καλό επίπεδο.

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

Βρήκα τι φταίει. Ο server. Το κατάλαβα καθώς δοκίμασα να τρέξω:

SELECT * FROM `clients` WHERE `pedio` = '1' OR `pedio` = '14' OR `pedio` = '1234' AND `seira` = '1' 

και του πήρε 32 δευτερόλεπτα για να εμφανίζει αποτελέσματα και μάλιστα εμφάνισε μόνο 23 αποτελέσματα ενώ έπρεπε να εμφανίσει 131. To ίδιο ακριβώς συμβαίνει και με LIKE '%1%'. Γι αυτό δεν έβλεπα τίποτα. Για κάποιο λόγο αργεί πολύ η εκτέλεση της εντολής ενώ στον πίνακα ελέγχου του παρόχου λέει: " Το ερώτημα χρειάστηκε 0.0027 δευτερόλεπτα. "

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

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

Άρα θες indexing, database optimization και να κασάρεις τα αποτελέσματα της βάσης σε ένα αποδοτικότερο τρόπο αποθήκευσης. Σε απλά Ελληνικά θες αποδοτικότερο σχήμα πχ. η σειρά να είναι indexed και ίσως οι σειρές να είναι ένα enum ή αποθηκευμένες σε ένα εξωτερικό table και το πεδίο να είναι indexed.

Ακόμη ίσως pagination και infinity scrolling μέσω ajax να δώσει τα αποτελέσματα που θες. (Ουσιαστικά έχεις το ίδιο να τα δείχνει όλα αλλά τα φέρνεις σιγά σιγά) πχ. μέσω https://infinite-scroll.com/ ή και https://stackoverflow.com/q/15181286

Τέλος δες:

https://dev.mysql.com/doc/refman/5.7/en/mysql-indexes.html

ENUM: https://dev.mysql.com/doc/refman/5.7/en/enum.html

Για caching: https://stackoverflow.com/q/6100186

 

(Σαφώς ένα κάνεις όλα τα παραπάνω θα έχεις το καλύτερο αποτέλεσμα)

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

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

H στήλη πεδίο τι τύπου είναι ?

άκυρο

CHAR(5). Η μέγιστη τιμή που μπορεί να πάρει είναι το "1234" που σημαινει ότι η καταχώρηση ανήκει και στις 4 κατηγορίες. Είτε πω LIKE '%1%' είτε πω pedio = '1' OR pedio = '2' τρώει σκάλωμα. Πήρα τηλ. τον πάροχο. Έχει πάει το θέμα σου στο αντίστοιχο τμήμα να ελεγχθεί να δούμε τι φταίει και περιμένουμε απάντηση από αυτούς, μου είπαν. Βλέπω στο τέλος να φτιάχνω 4 διαφορετικές στήλες τύπου TINYINT να τελειώνω.

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

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

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

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

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

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

Σύνδεση

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

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

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