PHP - Help Required To Fully And Properly Parameterize A Select Query
Hello All,
I'm having trouble trying to "wrap my head around" how I can make the query in my code below more efficient, elegant, and certainly immune to a SQL-injection attack
So, I have a form (which can be seen in the attached screenshot) which has the user first select a search-type via a dropdown listbox. The two choices pertain to two columns in the underlying table i.e. store_name and item_description. Once that selection is completed the user is expected to enter a search-term (which is typically in relation to the choice selected in the first prompt).
Now, what I would like to happen is that the query be created based on both, the value in the search-type prompt, as well as the value in search-term textbox, and of course, the query must be a parameterized prepared statement (to minimize the possiblity of a SQL-inection attach).
Essentially I would like to get rid of the following code (which I believe is potentially redundant, and contains a hard-coded column name between the WHERE and LIKE), to make things less complicated and more elegant/flexible
if ($searchtype == "store_name") { $sql = "SELECT * FROM `shoplist` WHERE store_name LIKE :searchterm ORDER BY store_name ASC"; } else if ($searchtype == "item_description") { $sql = "SELECT * FROM `shoplist` WHERE item_description LIKE :searchterm ORDER BY store_name ASC"; }Here's what I tried: // Tried this first but it didn't work...gave some kind of error pertaining to the parameter 2 // Prepare the query ONCE $query = "SELECT * FROM `shoplist` WHERE ? LIKE ? ORDER BY ? ASC"; $searchterm = '%' . $searchterm . '%'; $statement = $conn->prepare($query); $statement->bindValue(1, $searchtype); $statement->bindParam(2, $searchterm); $statement->bindValue(3, $searchtype); $statement->execute(); // ----------------------------------------------------------------------------------------------------------- // // Tried this as well, but was getting unexpected results (mostly all rows being returned, regardless of input) // Prepare the query ONCE $query = "SELECT * FROM `shoplist` WHERE :searchtype LIKE :searchterm ORDER BY :searchtype ASC"; $searchterm = '%' . $searchterm . '%'; $statement = $conn->prepare($query); $statement->bindValue(':searchtype', $searchtype); $statement->bindValue(':searchterm', '%' . $searchterm . '%'); $statement->execute();Here's the complete code (pertaining to the problem/request): // create short variable names if(isset($_POST['searchtype'])) { $searchtype=$_POST['searchtype']; } if(isset($_POST['searchterm'])) { $searchterm=trim($_POST['searchterm']); } if(isset($_POST['searchtype']) && isset($_POST['searchterm'])) { if (!get_magic_quotes_gpc()) { $searchtype = addslashes($searchtype); $searchterm = addslashes($searchterm); } } if(isset($_POST['searchtype']) && isset($_POST['searchterm'])) { // ****** Setup customized query ****** if ($searchtype == "store_name") { // The following statement is potentially open to SQL-inection attack and has therefore been REM(arked) // $sql = "SELECT * FROM `shoplist` WHERE " . $searchtype . " LIKE :searchterm ORDER BY store_name ASC"; // The following may not be open to SQL-injection attack, but has the column name hard-coded in-between the WHERE and LIKE clauses // I would like the the column name to be set based on the value chosen by the user in the form dropdown listbox for "searchtype" $sql = "SELECT * FROM `shoplist` WHERE store_name LIKE :searchterm ORDER BY store_name ASC"; } else if ($searchtype == "item_description") { // The following statement is potentially open to SQL-inection attack and has therefore been REM(arked) // $sql = "SELECT * FROM `shoplist` WHERE " . $searchtype . " LIKE :searchterm ORDER BY item_description ASC"; // The following may not be open to SQL-injection attack, but has the column name hard-coded in-between the WHERE and LIKE clauses // I would like the the column name to be set based on the value chosen by the user in the form dropdown listbox for "searchtype" $sql = "SELECT * FROM `shoplist` WHERE item_description LIKE :searchterm ORDER BY item_description ASC"; } $statement = $conn->prepare($sql); $statement->bindValue(':searchterm', '%' . $searchterm . '%'); $statement->execute(); ... ... ... }Thanks guys! Attached Files Search-Screen-SS.png 21.31KB 0 downloads Similar TutorialsHello all,
Based on the suggestion of you wonderful folks here, I went away for a few days (to learn about PDO and Prepared Statements) in order to replace the MySQLi commands in my code. That's gone pretty well thus far...with me having learnt and successfully replaced most of my "bad" code with elegant, SQL-Injection-proof code (or so I hope).
The one-and-only problem I'm having (for now at least) is that I'm having trouble understanding how to execute an UPDATE query within the resultset of a SELECT query (using PDO and prepared statements, of course).
Let me explain (my scenario), and since a picture speaks a thousand words I've also inlcuded a screenshot to show you guys my setup:
In my table I have two columns (which are essentially flags i.e. Y/N), one for "items alreay purchased" and the other for "items to be purchased later". The first flag, if/when set ON (Y) will highlight row(s) in red...and the second flag will highlight row(s) in blue (when set ON).
I initially had four buttons, two each for setting the flags/columns to "Y", and another two to reverse the columns/flags to "N". That was when I had my delete functionality as a separate operation on a separate tab/list item, and that was fine.
Now that I've realized I can include both operations (update and delete) on just the one tab, I've also figured it would be better to pare down those four buttons (into just two), and set them up as a toggle feature i.e. if the value is currently "Y" then the button will set it to "N", and vice versa.
So, looking at my attached picture, if a person selects (using the checkboxes) the first four rows and clicks the first button (labeled "Toggle selected items as Purchased/Not Purchased") then the following must happen:
1. The purchased_flag for rows # 2 and 4 must be switched OFF (set to N)...so they will no longer be highlighted in red.
2. The purchased_flag for row # 3 must be switched ON (set to Y)...so that row will now be highlighted in red.
3. Nothing must be done to rows # 1 and 5 since: a) row 5 was not selected/checked to begin with, and b) row # 1 has its purchase_later_flag set ON (to Y), so it must be skipped over.
Looking at my code below, I'm guessing (and here's where I need the help) that there's something wrong in the code within the section that says "/*** loop through the results/collection of checked items ***/". I've probably made it more complex than it should be, and that's due to the fact that I have no idea what I'm doing (or rather, how I should be doing it), and this has driven me insane for the last 2 days...which prompted me to "throw in the towel" and seek the help of you very helpful and intellegent folks. BTW, I am a newbie at this, so if I could be provided the exact code, that would be most wonderful, and much highly appreciated.
Thanks to you folks, I'm feeling real good (with a great sense of achievement) after having come here and got the great advice to learn PDO and prepared statements.
Just this one nasty little hurdle is stopping me from getting to "end-of-job" on my very first WebApp. BTW, sorry about the long post...this is the best/only way I could clearly explaing my situation.
Cheers guys!
case "update-delete": if(isset($_POST['highlight-purchased'])) { // ****** Setup customized query to obtain only items that are checked ****** $sql = "SELECT * FROM shoplist WHERE"; for($i=0; $i < count($_POST['checkboxes']); $i++) { $sql=$sql . " idnumber=" . $_POST['checkboxes'][$i] . " or"; } $sql= rtrim($sql, "or"); $statement = $conn->prepare($sql); $statement->execute(); // *** fetch results for all checked items (1st query) *** // $result = $statement->fetchAll(); $statement->closeCursor(); // Setup query that will change the purchased flag to "N", if it's currently set to "Y" $sqlSetToN = "UPDATE shoplist SET purchased = 'N' WHERE purchased = 'Y'"; // Setup query that will change the purchased flag to "Y", if it's currently set to "N", "", or NULL $sqlSetToY = "UPDATE shoplist SET purchased = 'Y' WHERE purchased = 'N' OR purchased = '' OR purchased IS NULL"; $statementSetToN = $conn->prepare($sqlSetToN); $statementSetToY = $conn->prepare($sqlSetToY); /*** loop through the results/collection of checked items ***/ foreach($result as $row) { if ($row["purchased"] != "Y") { // *** fetch one row at a time pertaining to the 2nd query *** // $resultSetToY = $statementSetToY->fetch(); foreach($resultSetToY as $row) { $statementSetToY->execute(); } } else { // *** fetch one row at a time pertaining to the 2nd query *** // $resultSetToN = $statementSetToN->fetch(); foreach($resultSetToN as $row) { $statementSetToN->execute(); } } } break; }CRUD Queston.png 20.68KB 0 downloads The Query:
$query = "SELECT * FROM ttn01 WHERE id = $_GET['id']";I am getting an error. $db->query( "UPDATE user_resources, user_buildings, user_units_nonbattle SET user_resources.uGold=user_resources.uGold+(user_buildings.uTownCenterLevel*(user_units_nonbattle.uMiner*10))" ); When the cron runs, it updates everyone the same regardless. Any idea what i'm doing wrong? Hi, i have a query string id=5&start=0 that i want to remove from the url and return the url without it. I am searching a cleaner way for doing it. Here is an example :
Before : http://www.example.com/?a=3&id=5&start=0 After : http://www.example.com/?a=3 Before : http://www.example.com/?id=5&start=0 After : http://www.example.com/ Before : http://www.example.com/?alpha=1&id=5&start=0&beta=2 After : http://www.example.com/?alpha=1&beta=2Thank you Edited by Dareros, 11 August 2014 - 04:06 PM. I have a simply query where I want show how many unique contests are there. So if I have 100 entries in a single contest, then each entry row will have the same contest id in this example. So even though there are 100 entries, they all belong to the same contest id. That means the echo of $total_contests should be 1. But instead I am getting the same count as the entry rows, which is 100. What am I doing wrong? $global_user_id = 1; $count_contests = $db->prepare("SELECT COUNT(*) FROM entries WHERE user_id = :user_id GROUP BY contest_id"); $count_contests->bindParam(':user_id', $global_user_id); $count_contests->execute(); $total_contests = $count_contests->fetchColumn(); echo $total_contests;
Hey guys, New to the forum and a newer user of PHP / MySQL. I am having trouble with some code I've written up. I don't seem to get any errors when running it, but it's not updating my database the way that it should. hopefully a simple fix. I am thinking that it must be on the MySQL side of things. Couple of things to start. My html form is comprised completely of drop down list inputs. I'm the only user so I thought this would be the easiest approach. Because of that I've made my PHP as follows: Code: [Select] <?php $season = $_POST['season']; $month = $_POST['month']; $day = $_POST['day']; $year = $_POST['year']; $time = $_POST['time']; $event = $_POST['event']; $game = $_POST['game']; $buyin = $_POST['buyin']; $connect = mysql_connect('localhost','root','') or die('can not connect'); if ($connect) { echo "connected to database"; } $db = mysql_select_db('dpl') or die('can not find database'); if ($db) { echo "DPL Selected"; } $query = sprintf("INSERT INTO events (season , month , day , year , time , event , game , buyin) VALUES ('%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s')", $season , $month , $day , $year , $time , $event , $game , $buyin ); if ($query) { echo "Your event has been added"; } ?> My connection is working, my database is selected and I'm even now getting confirmation that my query is working, but when i go to check my database there are no entries in it? any thoughts? I've tried the drop down variables as both VARCHAR and TEXT inputs in MySQL, but I can't seem to get it to work. Any help is greatly appreciated. i am unable to select total_comment from mysql table related to each post..
For detail information check http://stackoverflow...-query-in-mysql
I have this code below: Code: [Select] members_count <= ".$diff." || members_count >= ".$defmemcount." My test says $diff = 6 and $defmemcount = 11, members_count = 14 So how come this returns as if members_count isn't less or equal to 6 OR higher or equal to 11? Hi, Everyone! This my first time posting here. Anyways, I've been having problem getting the correct data from my database. I want to select the total_on/off_hours,exposure,plate_number, and terminal_status. But when I select the terminal_status, there are duplicates, I already used the DISTINCT function. It's a little hard to explain so, I'll just show you.
Here's a screen cap of my code trying to get just the terminal_status
What's the problem? What should I do? Any suggestions/help will be much appreciated.
ok, so I need to know how I can perform an operation of $total equaling $price1 + $price2 etc.... if they are not empty in the database............... does this make sense? Hi I need to do a SELECT query like $query = "SELECT name FROM myusers WHERE myidnum = ".$_SESSION['myid'].""; and put the results into an array like $myusers = array("David","John","Lucy","Sarah"); But I cannot figure out how to do this Can anyone help? Thanks hi i have this function for select / function select($table, $rows = '*', $where = null, $group = null, $order = null, $limit = null) this is what i do to display the records. $db->select('loan'); $records = $db->getResult(); foreach($records as $row) { $user = $row['id']; //$name = $row['firstname']; //print_r($row); echo $user; ?> the codes is running.but when i want to use WHERE id = $_POST['id']; this is what im doing. $db->select('member')->where(array('id' => $_POST['client'])); an error as occured where in function where is not existing. please help how to use the proper way of using select * $table where id=$id; in array. thanks Hi, i'm trying to select some entries from my DB, i don't quite understand what's the problem here, i'm using this: Code: [Select] //Customers Online $query = "SELECT COUNT(*) as Anzahl FROM customers WHERE status = 1"; $queryerg = mysql_query($query) OR die(mysql_error()); while($row = mysql_fetch_array($queryerg)){ $customers_online = $row[0]; } Which works fine, now i want to select by country and i'm doing this: Code: [Select] //Customers DE $query = "SELECT COUNT(*) as Anzahl FROM customers WHERE country = 'de'"; $queryerg = mysql_query($query) OR die(mysql_error()); while($row = mysql_fetch_array($queryerg)){ $customers_de = $row[0]; } Which doesn't work? If i print / echo $customers_de i just get a blank value, not even 0 or anything just blank. Any help ? Hello there, Having a nightmare here. It feels like what I need to do is really easy but I just can't get it to work. I have a table called "groups2" that holds a unique id and the name of an activity. I already have a query that finds the users selected groups using a while loop but I also want to show how many other members are in that group by counting the number of times the activity comes up or the id comes up. I don't know whether I need 2 while loops nested or what but I get the error Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource on line 32 which is highlighted. Can anyone help. I am no expert at php and still learning so some advice or example code would be great. $result = mysql_query("SELECT * FROM groups2 WHERE L_ID = ". $_SESSION['member_ID'] .";"); $data = mysql_query("SELECT COUNT('name') AS num FROM groups2 WHERE name = " . $row['name'] . ""); $count = mysql_fetch_assoc($data); $numbers = $count['num']; while ( $row = mysql_fetch_assoc($result) ) { echo("<tr> <td><font face='Arial, Helvetica, sans-serif' size='3'><strong>" . $row["name"] . "</strong></font></td> </tr><tr> <td><font face='Arial, Helvetica, sans-serif' size='1' color='#0000FF'><strong>Members (" . $numbers . ")</strong></font></td> </tr><tr> <td><hr width=95%><br></td> </tr>"); } Hello, Im trying to write a select query that has two conditions. First the playername is = username and second shipyard = 1 I keep getting a parse error: Parse error: syntax error, unexpected ',' in C:\wamp\www\SWB\planet1.php on line 85 Heres the code: Code: [Select] $tester = "1"; $colname_Planet1 = "-1"; if (isset($_SESSION['MM_Username'])) { $colname_Planet1 = (get_magic_quotes_gpc()) ? $_SESSION['MM_Username'] : addslashes($_SESSION['MM_Username']); } mysql_select_db($database_swb, $swb); $query_Planet1 = ("SELECT * FROM planet WHERE ShipYard = %s AND PlayerName = %s", GetSQLValueString($tester, "int"),GetSQLValueString($colname_Planet1, "text")); $Planet1 = mysql_query($query_Planet1, $swb) or die(mysql_error()); $row_Planet1 = mysql_fetch_assoc($Planet1); $totalRows_Planet1 = mysql_num_rows($Planet1); Please help :| Code: [Select] $DB->query("SELECT SUM(amount) FROM gold_logs WHERE from_id = {$ibforums->member['id']} GROUP BY from_id"); $data = $DB->fetch_row(); Okay, then I echo out Code: [Select] {$data['SUM(amount)']} but I want to select the sum(amount) from "to_id" ALSO! how can I add that into the query I dont want to use 2 queries, thanks Hi there
I am new to this forum and not much of a php expert. I hope you can assist me.
My problem is as follows:
I have a column consisting of several values (in this case: sceience, art, humanistics and music)
I would like to use the following mysqli query in order to count the appearances of each value in this column:
$query = "SELECT SUM (IF(department = 'science', 1, 0)) AS science, SUM(IF(department = 'art', 1, 0))-> AS art FROM new2"
I have tried lots of ways to loop the results but couldn't get the it working.
Can anyone suggest any idea?
Thanks
Hanan
hi im trying to use query to select from a table where the price is between to values that the user has to input such as min of 3 and max of 8 and return all the fields from the database where it is true im unsure how to do this but this is what i have so far
$res = pg_query ($conn, "SELECT ref,artist,composer,genre,title,album,label,price,description FROM music WHERE price = < && > "); I need to convert the following select statement to a pdo->query but have no idea how to get it working: SELECT t.id FROM ( SELECT g.* FROM location AS g WHERE g.start <= 16785408 ORDER BY g.start DESC, g.end DESC LIMIT 1 ) AS t WHERE t.end >= 16785408; Here's the code I'm trying: <?php $php_scripts = '../../php/'; require $php_scripts . 'PDO_Connection_Select.php'; require $php_scripts . 'GetUserIpAddr.php'; function mydloader($l_filename=NULL) { $ip = GetUserIpAddr(); if (!$pdo = PDOConnect("foxclone_data")) { exit; } if( isset( $l_filename ) ) { $ext = pathinfo($l_filename, PATHINFO_EXTENSION); $stmt = $pdo->prepare("INSERT INTO download (address, filename,ip_address) VALUES (?, ?, inet_aton('$ip'))"); $stmt->execute([$ip, $ext]) ; $test = $pdo->prepare("SELECT t.id FROM ( SELECT g.id FROM lookup AS g WHERE g.start <= inet_aton($ip) ORDER BY g.start DESC, g.end DESC ) AS t WHERE t.end >=inet_aton($ip)"); $test ->execute() ; $ref = $test->fetchColumn(); $ref = intval($ref); $stmt = $pdo->prepare("UPDATE download SET ref = '$ref' WHERE address = '$ip'"); $stmt->execute() ; header('Content-Type: octet-stream'); header("Content-Disposition: attachment; filename={$l_filename}"); header('Pragma: no-cache'); header('Expires: 0'); readfile($l_filename); } else { echo "isset failed"; } } mydloader($_GET["f"]); exit; It gives the following error: QuoteFatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '.144.181) ORDER BY g.start DESC, g.end DESC ) AS t WHERE t.end >=inet_aton(7' at line 1 in /home/foxclone/test.foxclone.com/download/mydloader.php:19 Stack trace: #0 /home/foxclone/test.foxclone.com/download/mydloader.php(19): PDO->prepare('SELECT t.id FRO...') #1 /home/foxclone/test.foxclone.com/download/mydloader.php(38): mydloader('foxclone40a_amd...') #2 {main} thrown in /home/foxclone/test.foxclone.com/download/mydloader.php on line 19 How do I fix this? The Script:
<?php include("connect.php"); ?> <?php echo "<h1>The Hashtag: </h1>"; if(isset($_GET['hashtag'])){ echo $_GET['hashtag']; } // Select the ID of the given hashtag from the "hashtags" table. $tqs = "SELECT `id` FROM `hashtags` WHERE `hashtag` = '" . $_GET['hashtag'] . "'"; $tqr = mysqli_query($dbc, $tqs) or die(mysqli_error($dbc)); $row = mysqli_fetch_assoc($tqr); // This prints e.g.: // 100 echo "<br/><br/>"; print_r($row['id']); // Select the threads from the "thread" table which contains the hashtag ID number. $tqs_two = "SELECT * FROM `thread` WHERE `hashtag_id` IN ('" . $row['id'] . "')"; $tqr_two = mysqli_query($dbc, $tqs_two) or die(mysqli_error($dbc)); $row_two = mysqli_fetch_assoc($tqr_two); echo "<br/><br/>"; print_r($row_two); ?>The script should select the rows by that ID number of the hashtag. It should look in the "hashtag_id" column of the table and see if that ID number can be found there, if it can be found there, then it should select that row. The ID numbers are inside that "hashtag_id" column separated by commas. Example: 98, 99, 100My Question: How to do the SQL query so it selects the rows by the hashtag ID number? Edited by glassfish, 17 October 2014 - 10:35 AM. |