How to make an SQL query based on some rules - php

I've got this HTML form where I have multiple input elements: text, radio, and so on. These are intended to be options, conditional items to apply in an SQL query in order to pull more specific data from a database.
For example, the first input field is a textbox, the second a radio button, and the third a SELECT with two options. With the first, I would add a LIKE %name% sentence in the SQL query. The second is a radio button group with, let's say, a color, so I would add a WHERE color = $item comparing the one chosen with the database column. The third would pretty much be just like the second.
Now, I guess I could just use if sentences comparing the three items, in order to know which one to add to the SQL query, but my question is: is there a smarter way to do it? Like an array checking if those variables are set (I'm still using an if here, so nevermind).
I program simple things from time to time, since I've never done anything significantly complex, but sometimes, even for simple things, no matter how hard I strive to design something, I just can't.
In this case, I really can't figure (imagine, visualize) how would I structure the PHP code along with the SQL query, in order to add the these three conditions to the WHERE clause.
I'd greatly appreciate if you can help me out here. If you need more details, just let me know.

You can just build your sql statement as you go.
A simple example:
$sql = "SELECT ... WHERE 1=1"; // 1=1 is just an example to get the WHERE out of the way
if (first condition / certain $_POST variable is set)
{
$sql .= " AND LIKE %...%";
}
if (second condition)
{
$sql .= " AND something=...";
}
// etc.
// run query

Just for adding another solution, I can suggest you using stored procedure.
http://www.mysqltutorial.org/mysql-stored-procedure-tutorial.aspx
http://www.brainbell.com/tutorials/MySQL/Using_Stored_Procedures.htm
You'll just need to pass values to a sp and generate where condition inside it.
There's another option to generate parameterized query in PHP to prevent SQL Injections.
Here are some links on this topic.
http://us2.php.net/manual/en/security.database.php
http://www.roscripts.com/PHP_MySQL_by_examples-193.html
http://www.webmasterworld.com/php/3110596.htm
http://am.php.net/mysql_real_escape_string

Related

Is it possible to add a add a number after select a value?

I trying to add +1 in a column after select but its not working, what I want is, when I make a search, the scripts adds +1 in a column to track how much searches I did.
Heres how it is now
$QUERY = "SELECT company FROM test WHERE number = '$number[0]' LIMIT 1";
And I want to add this
UPDATE users SET consultas=consultas+1 WHERE username = '$username'
If I add another $QUERY line the script breaks, any ideas ?
By nature, SELECT queries are for returning information from the database, not updating the database. To this end, triggers aren't even available for SELECT queries to react to the action. As such, if you want to increment a value, this must be done in a separate query, as an UPDATE query or possibly an INSERT ... ON DUPLICATE KEY UPDATE query if that better suits your needs.
You should execute those as two separate queries. Also, be very careful to ensure your data is properly escaped because it looks like you've forgotten to do that.
Be sure to check the result code of each as an error may occur at any time. If you use PDO there's a fairly robust error handling pattern you can follow.

PHP / MySQL Run Function From Multiple Results In Array

I'm not sure that I have the terminology correct but basically I have a website where members can subscribe to topics that they like and their details go into a 'favorites' table. Then when there is an update made to that topic I want each member to be sent a notification.
What I have so far is:
$update_topic_sql = "UPDATE topics SET ...My Code Here...";
$update_topic_res = mysqli_query($con, $update_topic_sql)or die(mysqli_error());
$get_favs_sql = "SELECT member FROM favourites WHERE topic = '$topic'";
$get_favs_res = mysqli_query($con, $get_favs_sql);
//Here I Need to update the Members selected above and enter them into a notes table
$insert_note_sql = "INSERT INTO notes ....";
Does anyone know how this can be achieved?
Ok, so we've got our result set of users. Now, I'm going to assume from the nature of the question that you may be a bit of a newcomer to either PHP, SQL(MySQL in this case), web development, or all of the above.
Your question part 1:
I have no idea how to create an array
This is easier than what you may think, and if you've already tried this then I apologize, I don't want to insult your intelligence. :)
Getting an array from a mysqli query is just a matter of a function call and a loop. When you ran your select query and saved the return value to a variable, you stored a mysqli result set. The mysqli library supports both procedural and object oriented styles, so since you're using the procedural method, so will I.
You've got your result set
$get_favs_res = mysqli_query($con, $get_favs_sql);
Now we need an array! At this point we need to think about exactly what our array should be of, and what we need to do with the contents of the request. You've stated that you want to make an array out of the results of the SELECT query
For the purposes of example, I'm going to assume that the "member" field you've returned is an ID of some sort, and therefore a numeric type, probably of type integer. I also don't know what your tables look like, so I'll be making some assumptions there too.
Method 1
//perform the operations needed on a per row basis
while($row = mysqli_fetch_assoc($get_favs_res)){
echo $row['member'];
}
Method 2
//instead of having to do all operations inside the loop, just make one big array out of the result set
$memberArr = array();
while($row = mysqli_fetch_assoc($get_favs_res)){
$memberArr[] = $row;
}
So what did we do there? Let's start from the beginning to give you an idea of how the array is actually being generated. First, the conditional in the while loop. We're setting a variable as the loop condition? Yup! And why is that? Because when PHP (and a lot of other languages) sets that variable, the conditional will check against the value of the variable for true or false.
Ok, so how does it get set to false? Remember, any non boolean false, non null, non 0 (assuming no type checking) resolves to true when it's assigned to something (again, no type checking).
The function returns one row at a time in the format of an associative array (hence the _assoc suffix). The keys to that associative array are simply the names of the columns from the row. So, in your case, there will be one value in the row array with the name "member". Each time mysqli_fetch_assoc() is called with your result set, a pointer is pointed to the next result in the set (it's an ordered set) and the process repeats itself. You essentially get a new array each time the loop iterates, and the pointer goes to the next result too. Eventually, the pointer will hit the end of the result set, in which case the function will return a NULL. Once the conditional picks up on that NULL, it'll exit.
In the second example, we're doing the exact same thing as the first. Grabbing an associative array for each row, but we're doing something a little differently. We're constructing a two dimensional array, or nested array, of rows. In this way, we can create a numerically indexed array of associative arrays. What have we done? Stored all the rows in one big array! So doing things like
$memberArr[0]['member'];//will return the id of the first member returned
$memberArr[1]['member'];//will return the id of the second member returned
$lastIndex = sizeof($memberArr-1);
$memberArr[$lastIndex]['member'];//will return the id of the last member returned.
Nifty!!!
That's all it takes to make your array. If you choose either method and do a print_r($row) (method 1) or print_r($memberArr) (method 2) you'll see what I'm talking about.
You question part 2:
Here I Need to update the Members selected above and enter them into a notes table
This is where things can get kind of murky and crazy. If you followed method 1 above, you'd pretty much have to call
mysqli_query("INSERT INTO notes VALUES($row['member']);
for each iteration of the loop. That'll work, but if you've got 10000 members, that's 10000 inserts into your table, kinda crap if you ask me!
If you follow method two above, you have an advantage. You have a useful data structure (that two dim array) that you can then further process to get better performance and make fewer queries. However, even from that point you've got some challenges, even with our new processing friendly array.
The first thing you can do, and this is fine for a small set of users, is use a multi-insert. This just involves some simple string building (which in and of itself can pose some issues, so don't rely on this all the time) We're gonna build a SQL query string to insert everything using our results. A multi insert query in MySQL is just like a normal INSERT except for one different: INSERT INTO notes VALUES (1),(2),(x)
Basically, for each row you are inserted, you separate the value set, that set delineated by (), with a comma.
$query = 'INSERT INTO notes VALUES ';
//now we need to iterate over our array. You have your choice of loops, but since it's numerically indexed, just go with a simple for loop
$numMembers = sizeof($memberArr);
for($i = 0; $i < $numMembers; $i++){
if($i > 0){
$query .= ",({$membersArr[$i]['member']})";//all but the first row need a comma
}
else {
$query .= "({$membersArr[$i]['member']})";//first row does not need a comma
}
}
mysqli_query($query);//add all the rows.
Doesn't matter how many rows you need to add, this will add them. However, this is still going to be a costly way to do things, and if you think your sets are going to be huge, don't use it. You're going to end up with a huge string, TONS of string concats, and an enormous query to run.
However, given the above, you can do what you're trying to do.
NOTE: These are grossly simplified ways of doing things, but I do it this way because I want you to get the fundamentals down before trying something that's going to be way more advanced. Someone is probably going to comment on this answer without reading this note telling me I don't know what I'm doing for going about this so dumbly. Remember, these are just the basics, and in no way reflect industrial strength techniques.
If you're curious about other ways of generating arrays from a mysqli result set:
The one I used above
An even easier way to make your big array but I wanted to show you the basic way of doing things before giving you the shortcuts. This is also one of those functions you shouldn't use much anyway.
Single row as associative(as bove), numeric, or both.
Some folks recommend using loadfiles for SQL as they are faster than inserts (meaning you would dump out your data to a file, and use a load query instead of running inserts)
Another method you can use with MySQL is as mentioned above by using INSERT ... SELECT
But that's a bit more of an advanced topic, since it's not the kind of query you'd see someone making a lot. Feel free to read the docs and give it a try!
I hope this at least begins to solve your problem. If I didn't cover something, something didn't make sense, or I didn't your question fully, please drop me a line and I'll do whatever I can to fix it for you.

how to select entries from database for particular fields entered in php

I have php page thats taking values for startdate, enddate, hotelname, city, price and type from the user.
Now i need to check my database for only the values that are entered by the user. Is that possible? For any entry that is left blank, the corresponding condition is not applied (e.g., if city is left blank, all cities are considered).
Like if the user enters only the hotelname then i need to select * from hotel where hname = hotelname.
If i go on checking for all the possible set of conditions then it will be to long like 63 combinations are possible!! so is there any way out? please help! Thanks.
You should write a method that loops through the input vars and looks for valid column names instead of handling each input individually. Then make sure you are using prepared statements in your SQL (mysqli, PDO).
To check for specific input vars, you should perform an
if (isset($_POST['var']) && !empty($_POST['var']))
If each field needs special attention or separate database tables, then you will most likely need to handle each field individually.
It ultimately depends on your needs. But in my experience there is always a way to do it pro-grammatically.
When you build your query in your code, only include the items that have values in them.
You ARE building your query dynamically aren't you?

mysql INSERT and combining $_POST

I have 2-3 questions regarding my sql INSERT and how to go about combining multiple $_POST into one field.
i'm having problems with my INSERT statement everything was working till I added m_id=".intval($id)."
for field m_age I need to combine/insert the following three $_POST['month'] $_POST['day'] $_POST['year'] into it. Should I create a var $age = $_POST['month'] + ...; then insert $age into m_age separately?
same as 2. I want combine $_POST['feet'] and $_POST['inches'] into m_height
code:
$fields = explode(" ", "m_id m_pos m_name m_age m_btype m_height");
$query = "INSERT INTO meminfo SET m_id=".intval($id).", ".dbSet($fields, "m_" + $_POST['add']);
Without knowing what your dbSet() function looks like I can hazard a few guesses:
Your $fields array contains an m_id field, which you are already setting explicitly when you added the m_id=".intval($id)." portion. This could be why you're having problems there.
You want to insert into an "age" field using month, day, and year? Are you calculating the age based on those 3 parameters assuming they are a birthdate? If so I'd say you probably are best off doing that calculation and assigning the result to an $age variable and using that in your insert.
Same as #2 although conversion of feet and inches to a combined total in one of those units is a simpler calculation and so could be done inline with your insert statement.
Basically when it comes down to 2 & 3 you can go either way but your code will probably be much more readable (and therefore maintainable by you and/or others in the future) if you separate out the calculations from the formation of the SQL query.
everything was working till I added m_id=".intval($id)."
this is not true.
While m_id=".intval($id)." being correct statement,
a dbSet($fields, "m_" + $_POST['add']); one makes absolutely no sense.
but you are right, the dbSet() function is intended to be used like that
$_POST['m_id'] = $id;
and 'm_id' will be added to the set automatically. Same for the other artificial fields
However, adding an id (assuming autoincrement field) into insert query makes no sense.
Anyway, seeing your struggle with basic PHP syntax I am going to withdraw my proposal for using dbSet() function.
You have to write your inserts by hand, until you get familiar with them.
Otherwise no function will do no good for you.
The particular problem obviously coming from the m_ prefix you are using for all your fields. A strange whim making things unnecessary complicated. You'd better get rid of it.

PHP Array as input to Stored Procedure

This is what i am doing now : - in PHP
foreach($array as $value)
{
$query = select abc from tblname where colname =" .$value.
// fire query
}
then i create array of these values and display accordingly.
The PROBLEM: -
I have applied foreach, which fires the query every time it encounters a value in the array.
result, if i have 10 values in my array it fires 10 queries. and uses network 10 times, result slow output.
What i want -
I want to give the array to a stored procedure which shall give me a resultset which will have the outputs corresponding to all the elements in the array.
I know this can be done but do not know how.
the mysql doesnot take arrays as datatype.
the result shall be that network shall be used only once, despit of any number of values in the array.
LIKE -
StoredProcedure(inputMysqlARRAY) // not possible, need a workaroung
{
// fire simple select(same) query for each value.
}
then call this stored procedure from PHP and input array. // need workaround.
You just have to be smarter about your calls. For instance, keeping cached DB objects around and that sort of thing.
Without knowing more about your code (your question is fairly garbled), it seems that if your query is something like this:
$query = "select abc from tblname where colname =" .$value; // run 10 times.
You really just need to write smarter code:
$values = array(); // Now, populate this array.
// When you're done, run the query:
$query = 'select abc from tblname where colname IN (\''.implode('\',\'', $values).'\')';
Generally, we refer to this as Dynamic SQL and is the underpinning for how things are typically done today. A stored procedure (or, based on how I read your question, stored function) is useful at times, but is somewhat antiquated as a first-order methodology for interfacing with SQL. The DB guys still sometimes swear by it, but I think that even they are fairly well in consensus that smarter queries are always better.

Categories