Setup mysql query with dynamic datasets per section - php

Ok, so my main issue is with anything that goes between WHERE and ORDER BY, LIMIT, etc.
I have it currently setup like the below:
SELECT " . $column_string . " FROM " . $table_name . " " . $query_join . " " . $where . " " . $query_end . " " . $query_limit
My issue is this, I have it setup to check each variable with escape string but when you come to $query_end which would hold test = '1' AND test2 = '2' etc. I have that section setup to allow you to send the whole string in one go. But of course if you check that it gets turned into test = \'1\' AND test2 = \'2\'.
The only thing I could think of doing was seperating it into some wierd array like [test2 = ],[2] but that doesn't work for (test1 = '2' OR test2 = '3') although I could make it work I really don't want to do it that way.
Can anyone suggest a better solution to the above problem? Also is there another item for checking for injection outside of mysql-real-escape-string?
The whole reason for this setup is to allow me to send multiple queries via ajax using json and then sending all the data back in a 3 level array.

Nothing actually wrong with "weird" array.
Every custom search solution is based on the similar approach - a series of conditions to assembly a WHERE clause dynamically.
I have no idea though, why would you need a fieldset or a table set by a user. But the idea would be quite the same. Just don't forget to verify all the identifiers and operators against a hardcoded white list.

Related

PHP SELECT returns empty using IN and implode

I have been at this for almost two hours and I'm pretty sure I'm just missing something simple. I have tried multiple iterations without success. SO searches have given insights but nothing exactly like this to see were I'm going wrong. Your input will be appreciated.
I have an array built [$prime_ids] made up of user IDs (individual email addresses). This is the look of the finished array:
["james.pruit#abcnet.com", "dan.smith#abcnet.com", "nathan.jones#abcnet.com", ...
Now I need to find matches in this list against matches in a database table. Note: there can be multiple matches with the information contained in the table (meaning a single user ID may show up multiple times in the list). That is being done for a specific reason.
My understanding is I need to use implode to make this work. Here is my query:
$sql_query = "SELECT * FROM worksheet4 WHERE worksheet4.user_id IN (" . implode(",", $prime_ids) . ");";
$result = $dbc->query($sql_query);
I then run a loop to build a second array ($kp_positions). Here is my code:
while($row = mysqli_fetch_assoc($result)) {
$kp_positions[] = $row;
}
This returns an empty array. While debugging I tried the same SELECT query using WHERE instead of IN and implode:
WHERE user_id = 'dan.smith#abcnet.com'";
... and it works perfectly (but only for this single-user). Thinking this might have something to do with single quotes (') in the implode statement I tried every possible combination that made sense without avail. Because this works perfectly with a single user ID, where my going wrong in my implode statement? Or, am I going about this the wrong way? Thank you.
if you print your query you will get something like this:
SELECT * FROM worksheet4 WHERE worksheet4.user_id IN (james.pruit#abcnet.com,dan.smith#abcnet.com,nathan.jones#abcnet.com);
Note that each member within the "in" should be wrapped in quotes
so try to run this line:
$sql_query = "SELECT * FROM worksheet4 WHERE worksheet4.user_id IN ('" . implode("','", $prime_ids) . "');";
and get
SELECT * FROM worksheet4 WHERE worksheet4.user_id IN ('james.pruit#abcnet.com','dan.smith#abcnet.com','nathan.jones#abcnet.com');
Another option, in my opinion better, is to use json_encode() to quote it.
$prime_ids = array_map('json_encode', $prime_ids)
https://3v4l.org/HPL2o
Then without quotes, which json_encode() adds for you:
$sql_query = "SELECT ... IN (" . implode(",", $prime_ids) . ")";
This will escape quotes that may exist, which is good.

Problems composing php sql query for postgresql table using LIKE

I am trying to retrieve data from a postgresql table therefore I have written a code. Now I am trying to compose the sql query but it isn't working. With my query I am trying to search in the table genes_searchterms and find all geneID matching where in the column types the value is equal to Pathway and where in the column searchterm the word aging is present.
Bellow the code to compose my query:
$sqlquery = "SELECT DISTINCT \"gene_id\" FROM \"" . \"genes_searchterms\" .
"\" WHERE ". "(\"types\" LIKE '". \"Pathway\" . "'
AND \"searchterm\" LIKE '" . \"%aging%\" ."') ";
Is there something wrong in the composition of my query? I use drupal and I don't get any errors when executing the code. I can't figure out where I got it wrong.
I use PostgreSQL 9.2.23.
In the fiddle is a part displayed of my table
https://www.db-fiddle.com/f/t7ThJ7Aen9XYzv2EtepinP/0
I've tried to get your Query up and running in db-fiddle. I also got no result, so I rechecked your condition and tried them separately. The error was in the "searchterm" condition.
You're using the ~* operator wich matches, according to the documentation, a Regex case insensitive. Since % isn't a pattern in Regex it matches "%aging%" literally. Only if you use LIKE in the query. % will be used as a wild card.
You could ether use a correct Regex or switch to LIKE.

How do I add a vote to my database in a form?

alright,The problem is I can't get my database to add a vote to it on the votes page or my database after an individual on the previous page clicks submit for there vote to a question. I've tried things like $vote = $vote + 1 in my PHP code and then displaying it with SQL through $command but that doesn't work and many other things I've tried like making a variable = 1 ($avote = 1) so I'm kinda stuck, someone told me that I can just add 1 by doing this -
$votes = $row['Votes' . $i] + 1; and then I'd have to display it under somehow but I couldn't figure it out, here's my code within my page to retrieve the information and add it to my database and page (I've taken out unneccesary HTML table tags for a clearer view):
// if $row is false, then the pollid must have been wrong
if ($row) {
// display the poll
echo '<h1>' . $row['Title'] . '</h1>';
echo '<p><b>' . $row['Question'] . '</b></p>';
for ($i = 1; $i <= 4; $i++) {
$answer = $row['Answer' . $i];
$votes = $row['Votes' . $i];
$avote = 1;
$command = "UPDATE FROM polls SET $answer WHERE $answer='$answer+$avote'";
$stmt = $dbh->prepare($command);
$stmt->execute(array($_SESSION['Votes']));
If my friend is right about the $votes = $row['Votes' . $i] + 1; can someone please let me know how I'd display it within my $command SQL code:
$command = "UPDATE FROM polls SET $answer WHERE $answer='$answer+$avote'";
Please and Thank you for any insights.
Do you get error messages?
It sounds like you're trying to show the results of a poll (after the user submits their own vote), but you're having trouble retrieving the results of the poll. Since the poll results need to persist across users and sessions, you have to store it somewhere. I guess that's what $answer is in your database?
Your UPDATE query is a bit broken. First, you should make sure it works properly without the variables, I like to go the the command line client or a graphical tool like phpMyAdmin. It might look more like:
UPDATE polls SET result = result + 1 WHERE poll_id = 1;
Where poll is your table and result and poll_id are columns in your table.
It appears as if you're trying to ask the user multiple questions, so you would have a different poll_id for each one, and use a hidden form field to get the value for the poll_id. You appear to be using the $row array for that now, but it seems fragile and it won't scale as you build more poll options (well, technically it will scale up, but you won't ever be able to remove a question or get rid of old polls.
You seem to be using PDO (since the "object oriented style" mysqli execute takes a void parameter and none of the PHP libraries that speak to SQL Server seem to have that exact syntax), but then I would expect your prepare statement to have question marks for the variables rather than direct substitution. See the PHP manual for details if you're unclear about the proper syntax, but hopefully you've already been through that before coming here.
Once you get those issues cleaned up, if you have further problems it should be a bit easier to trace through what's going on.

Old SQL database- trying to store string with text with spaces

I'm working on an old mySql database, trying to insert new rows. The code is below (I know it's ugly- just trying to get it to work before making it work well!).
Everything seems to work unless the $newbuilding variable includes a space. That variable will always be a string, but if that string includes a space (for example, "Building 01"), anything after the space is omitted when it's inserted into the table. Works fine if there are no spaces.
Any idea what I'm doing wrong? Thanks for any feedback!
$SQLstmt = "insert into homes_mail_lists set " .
"`tbl_id` = ${tbl_main["tbl_id"]}, " .
"`item_id` = ${Iitem_id}, " .
"`building` = '${newbuilding}', " .
"`updt_user` = '${cp_valid_user}', " .
"`updt_dttm` = null";
Just figured out my problem- sorry for wasting anyone's time! If you're curious or run into a similar problem- my issue wasn't with the SQL, it was with the html provided to the $newbuilding variable (it was not enclosed in quotes, so wasn't recognizing two words as one string).

Variable string in string in variable ?? PHP

I am coding a reoccurring sql select with a varying clause. In the clause i have a PHP variable (supposed to be replaced later within a WHILE.
My code:
$custaccount_id_clause = "(SELECT DISTINCT(custaccount_id) AS custaccount_id FROM accountcomms_def_tbl a WHERE subagent_def_id = " . '\'$interest_id\'' . " AND agentorder > (SELECT agentorder FROM accountcomms_def_tbl WHERE subagent_def_id = '$subagent_def_id' and custaccount_id = a.custaccount_id))";
$subagent_def_id works becuase its already defined.
$interest_id does NOT work because its not defined. I am trying to substitute it with $interest_id later on during a while loop in which I am calling $custaccount_id_clause as part of a while loop:
$allresidual_sql = mysql_query("SELECT SUM(txn_value) as txn_sum, COUNT(DISTINCT(custaccount_id)) AS accounts FROM account_stmnt_tbl WHERE txn_type IN ('Fixed Residual','Variable Residual','One Time Adjustment') AND custaccount_id IN ". $custaccount_id_clause)or die(mysql_error());
Within the $custaccout_id clause, I have the text '$interest_id' which I want PHP to replace the variable within. It is not replacing the variable.
This is a quick example app I am writing for a demo, please dont lecture me about which API I am using, as I wont be coding anything that goes into production! :)
A simple way to use the first variable you wanted to use ($interest_id) would be to test it and place a null inside instead of the variable in a direct fashion like this:
WHERE subagent_def_id = '" . ($interest_id ? $interest_id : null) . "' AND agentorder
This should protect you from getting errors about the variable/property not being defined.
The substitution part is what intrigues me... do you mean, at a given point in your structure, replacing $interest_id with, let's say, $my_other_variable? You could accomplish that if you model the whole SQL query as a string and, depending on a given condition, you re-write it.
Something like this could work (it's just a simple test, adapt it for your needs if you see it fit):
$query = ($a ? "SELECT * FROM `products` WHERE `price` > '{$a}';" : "SELECT * FROM `products` WHERE `date_added` < '{$b}' AND price > 20;");
That's if I have understood you correctly. Otherwise, I suspect you want to use the eval() function for parsing your encoded string and making PHP process your variable as you wish.
Hope that helps

Categories