PHP Select all variables which are equal to 1 - php

I am trying to get an SQL-query to be dynamic.
These are the steps I'm taking:
Step 1:
//Here the user sets which table fields will be used:
<input type="checkbox" name="id" value="1"> ID
<input type="checkbox" name="name" value="1"> name
<input type="checkbox" name="email" value="1"> email
Step 2:
//Here I see what fields the user wants to use and set a variable to 1
<?php
if (isset($_POST['id']) && $_POST['id'] == "1")
{
$form_id='1';
}
//etc etc
?>
Step 3:
//And finally here's the sql query
$sql = mysql_query("select * from mytable");
Now I need to set the fields that the user selected to the query.
For example if the user checks only id and name, then it should look like this:
$sql = mysql_query("select id, name from $table");
What's the best way of doing this?

Why not instead push all of the field names into an array instead of setting disparate variables?
$fields = [];
if(isset($_POST['id']) && $_POST['id'] == 1) {
$fields[] = 'id';
}
Then you should just be able to implode the array together in order to get your select columns:
$fields = implode(', ', $fields);
Also, #h2ooooo is correct, please avoid using mysql_ functions. They are depracated and will be removed in future versions of PHP.

Simply you can use ! empty() function instead of isset() && $_post['id']==1
$select_fields = array();
if(!empty($_POST['id']))
$select_fields[] = 'id';
if(!empty($_POST['name']))
$select_fields[] = 'name';
if(!empty($_POST['email']))
$select_fields[] = 'email';
$query_fields = implode(', ', $select_fields);
$sql = mysql_query("select $query_fields from $table");

The basic solution is to check which parameters are set and equal to one and push the column name into an array if that's the case.
You can then loop through the array and concatenate the fields to the query, making it dynamic.
The biggest concern here is that you're using mysql_* functions which are deprecated. I recommend using PDO since I find them comfortable and handy to use but mysqli is also viable.
With PDO and mysqli you'll be able to use prepared-statements which are the best way to prevent injections so please use them.
Solution
Using the ternary operator, we can check which parameters are set and assign the field names accordingly.
$id = isset($_POST['id']) && $_POST['id'] == 1 ? 'id' : null;
$name = isset($_POST['name']) && $_POST['name'] == 1 ? 'name' : null;
$email = isset($_POST['email']) && $_POST['email'] == 1 ? 'email' : null;
I do this becuse I find the ternary operator prettier than multiple if-statements.
Let's construct an array with the variables that we just created:
$parameters = array($id, $name, $email);
By simply checking which fields are not null we can easily construct the columns array.
$columns = array();
foreach($parameters as $column)
{
if($column != null)
{
$columns[] = $column;
}
}
Finally we can implode the columns together, separating them with a comma:
$activeColumns = implode(",", $columns);
So you can use $activeColumns as a part of your query, which is then recommend to be prepared afterwards.

Related

PDO filter system with Ajax. Is there a better way?

I am trying to filter some inputs of the user with select boxes. I am figuring if there is a better way doing this.
if(isset($_POST['action']))
{
$sql = "SELECT * FROM occasions WHERE naam IS NOT NULL";
if(isset($_POST['merk'])){
$merk = $_POST['merk'];
$merkQuery = implode(',', array_fill(0, count($merk), '?'));
$sql .= " AND merk IN(".$merkQuery.")";
}
if(isset($_POST['brandstof'])){
$brandstof = $_POST['brandstof'];
$brandstofQuery = implode(',', array_fill(0, count($brandstof), '?'));
$sql .= " AND brandstof IN(".$brandstofQuery.")";
}
//We prepare our SELECT statement.
$statement = $pdo->prepare($sql);
if(isset($_POST['merk'])){
//Execute statement.
$statement->execute(array_merge(array_values($merk)));
}
if(isset($_POST['brandstof'])){
//Execute statement.
$statement->execute(array_merge(array_values($brandstof)));
}
if(isset($_POST['merk']) && isset($_POST['brandstof']))
{
$statement->execute(array_merge(array_values($merk), array_values($brandstof)));
}
else
{
$statement->execute();
}
}
Cause if there are many select boxes that need filtering, the code would become long. I was wondering if there is a better way of filtering multiple select boxes.
Here is an example: link
I would suggest renaming the post variables; grouping them into a single two dimensional array.
<input type="checkbox" name="data[merk][bmw]" />
<input type="checkbox" name="data[merk][skoda] />
and so forth.
What this does, is it allows you to use a foreach to iterate through whatever values are checked.
$data = $_POST['data'] ?? []; // null coalesce defaults to a blank array if post var is null
foreach($data as $category=>$val) {
settype($val, 'array');
$query = implode(',', array_fill(0, count($val), '?'));
foreach($val as $k=>$v) {
$params[] = $k;
}
// DON'T DO THIS!
$sql .= " AND $category IN(".$query.")";
}
The reason you shouldn’t do it as shown is because you should never build a query with user-supplied data.
What you can do, however, is map user-supplied data with hard-coded data.
$map = [
// form value => db field
'merk' => 'MERK',
'brandstof' => 'BRANDSTOF',
// ... etc
];
and then when building your query,
$sql .= " AND $map[$category] IN($query)";
In the meantime, you have built your parameters in $params.
—-
Bottom line, what we have done is refactor the code since we were noticing things getting repeated. For example, you were having to repeat code for each occasion(?). One solution would be to continue to check each post value and call a function to calculate the ?s. But even then, it would be repetitive to type out all those isset()s.
In retrospect, it probably would have been better to do inputs like this:
<input type="checkbox" name="data[merk][]" value="bmw" />
<input type="checkbox" name="data[merk][]" value="skoda" />
This would no doubt be more intuitive, although you would still have to build the params array.
foreach($val as $v) {
$params[] = $v;
}

Send only filled inputs values to database via SQL

I have dozens of inputs in an HTML table one can use to enter numerical values. When submit button is pressed all inputs values are added to their corresponding column in the SQL table via post method. Value of <input name="A1> will be sent to column A1 in SQL table, <input name="A2> to column A2, and so on.
I'm currently using something like this (but with dozens of parameters) to insert data in my table :
$sql = "INSERT INTO all_stats_table (A1, A2, A3) VALUES ($A1, $A2, $A3)";
Problem with this approach is that every input needs to be filled or it will result in an SQL error. I initially used php to set all empty inputs value to 0 before sending everything to database, but I don't think this method is the most efficient way to go.
I would rather like to dynamically check which inputs are actually filled and only send their values to the table instead of converting every empty input value to 0 and having to send everything to the database.
I've already set all default values to 0 in SQL, but I don't know how to only send filled input values via SQL. I tried using a php foreach loop but I'm definitely having trouble finding the right SQL syntax.
Is what I'm trying to do possible ? If not, what would be the best practice to make this process more efficient ?
Thank you for your help
EDIT : attempt to adapt akash raigade's great solution to non-numbered SQL columns :
HTML :
<input name='name'>
<input name='address'>
<input name='age'>
PHP :
$Field_list = array ('name','address','age');
$field_string = '';
$input_string = '';
foreach ($_POST as $userInfo=>$userInfo_value) {
if (isset($userInfo)) {
if ($field_string == '') {
$field_string = $field_string.$userInfo; //problem here ?
$input_string = $userInfo_value; //problem here ?
}
else {
$field_string = $field_string.','.$userInfo; //problem here ?
$input_string = $input_string.','.$userInfo_value; //problem here ?
}
}
}
$sql = "INSERT INTO protocole_test (".$field_string.") VALUES (".$input_string.")";
echo $sql ; //check query formed
[Upgraded version]
Basic idea is that we keep NAME attribute of INPUT same as table column-name where it is gonna be stored.Then with help of input tag name and value which are filled we prepare SQL statement which have only required (FILLED) columns and values.
For given example consider following MYSQL table :
sr.no.|name|age|gender
CODE [Tested]:
<input name="name" >
<input name="age" >
<input name="gender" >
<input type='submit'>
<?php
$field_string ='';
$input_string='';
foreach ($_POST as $userInfo=>$userInfo_value){
if($userInfo_value !=''){
echo $userInfo."->".$userInfo_value;
if ($field_string == '') {
$field_string = $field_string.$userInfo;
$input_string = $userInfo_value;
}
else {
$field_string = $field_string.','.$userInfo;
$input_string = $input_string.','.$userInfo_value;
}
}
}
$sql = "INSERT INTO protocole_test (".$field_string.") VALUES (".$input_string.")";
echo $sql ; //check query formed
?>
[original answer]Have a look at following code :
<input name='a1' id='input_for_name'>
<input name='a2' id='input_for_class'>
<input name='a3' id='input_for_seat.no'>
.
.
<input name='an' id='input_for_n'>
Now
<?php
//you must be having field list to be inserted i.e
//INSERT INTO all_stats_table >>>(A1, A2, A3)<<< VALUES ($A1, $A2, $A3)
//A1,A2,A3 is field list here
//so save them into an array.
$Field_list = array ('A1','A2','A3',.......'An');
//Now get which input_field is inputted by :
$i=0;
$field_string = '';
$input_string = '';
for($i<n){
if(isset($_POST['a'.$i])){
if ($field_string == ''){
$field_string = $field_string.$Field_list[$i];
$input_string = $_POST['a'.$i];
}
else {
$field_string = $field_string.','.$Field_list[$i];
$input_string = $input_string.','.$_POST['a'$i];
}}}
$sql = "INSERT INTO (".$field_string.") VALUES (".$input_string.")";
//to check query formed
echo $sql ;
?>
Explanation :
We check which input field is FILLED , if it is field we add its FIELD into FIELD LIST and ITS VALUE in INPUT LIST finally we GENERATE SQL STATEMENT.
Just check if they are not defined or empty, and if so, define them.
if ( (!isset($_POST['A1'])) || (empty($_POST['A1']) ){
$A1 = '0';
} else {
$A1 = $_POST['A1'];
}
I'm not able to test this and it may need some debugging, but you could create a function, then call the function for each input. Something like...
function chkinput($input){
if ( (!isset($_POST[$input])) || (empty($_POST[$input]) ){
$$input = '0';
} else {
$$input = $_POST[$input];
}
return $$input;
}
// You could potentially loop through the post array
// but here I just call the function once per input
chkinput('A1');
chkinput('A2');
...
chkinput('A12');
You loop through the $_POST array and check if it has a value. If it does concatenate it to an variable. Like this:
$fields = "";
$values = "";
foreach($_POST as $key=>$value){
if($value != ''){
if($value != end($_POST)){
$fields .= $key . ", ";
$values .= "'" . $value . "', ";
}else{
$fields .= $key;
$values .= "'" . $value . "'" ;
}
}
}
$sql = INSERT INTO protocole_test ($fields) VALUES ($values) ;
Your SQL would look like :
INSERT INTO protocole_test (A1, A2, A3) VALUES ('A1', 'A2', 'A3')

passing a php variable in $_POST

i have a question regarding passing a php variable in the $_POST knowing that i named my buttons using the same variable because i want the buttons to have unique names.
while($row = mysql_fetch_array($query)){
$friend_id = $row['friend_id'];
$result = mysql_query("SELECT username FROM users WHERE user_id = '$friend_id'");
if (mysql_num_rows($result) > 0) {
$friendname = mysql_result($result,0,"username");
$friendname = sanitize($friendname);
echo '<input type = "submit" id='. $friend_id .' name ='.$friend_id.' class = "member" value ='. $friendname.' /><br>';
}
here where i am trying to pass it but it is not working
print_r($_POST);
if(isset($_POST['name'])){
$signers = mysql_query("SELECT friend_id FROM friends WHERE user_id = $session_user_id ");
$count = mysql_num_rows($signers);
if($count == 0){
echo "<p>you need to add team members</p>";
}
else{
while($row = mysql_fetch_array($signers)){
$signer_id .= $row['friend_id'];
}
echo '<p>'.$signer_id . '</p>';
}
$request = mysql_query("INSERT INTO requests VALUES ('','$user_id','$fid','$fname','$signer_id')");
}
else {
echo '<p> not working </p>';
}
both of those sections are in the same php page
You're not passing a variable around, you're passing a value so this line -
if(isset($_POST["'$friend_id'"])=== true){
needs to be changed to this -
if(isset($_POST['name'])){
The name attribute (along with the value) of each input is what is passed in a POST. You're just checking to see if the name parameter has a value, if it does then you can act on it with other code.
In addition please stop using mysql_* functions. They are no longer maintained and are officially deprecated. Learn about prepared statements instead, and consider using PDO.
The condition in the second piece of code should be without quotes:
if (isset($_POST[$friend_id])) {...
The part === true isn't necessary in this case, I've removed it.
You should look into predefining any variables you intend to use.
function input_post ($value, $default) {
return isset($_POST[$value]) ? $_POST['value'] : false;
}
Then use the post as so, this would prevent any not set errors
$friend_id = input_post('friend_id');
if ($friend_id) {
// If friend_id is set, do this
}
else {
// If friend_id is false or unset
}

How i will make a LIKE search in the following code?

I've got the following code which is something like a form search engine with multiple inputs where the results are kinda absolute concerning the number of characters etc(perfect match)
.
// build array of field names=============================================================================
$fields=array('user','customer','vessel','country',
'port','eta','service_station','type_of_service',
'case_reference','status');
// initialize empty array for WHERE clauses
$wheres=array();
// loop through field names, get POSTed values,
// and build array of WHERE clauses, excluding false values
foreach ($fields as $field) {
// get existing field value from POST, mark missing or empty value as FALSE
${$field} = isset($_POST[$field]) && trim($_POST[$field])!=''
? trim($_POST[$field]) : false;
// add to array of WHERE clauses only if value is not FALSE
if (${$field}) { $wheres[]="$field='".${$field}."'"; }
}
// build SELECT statement from WHERE clauses
$sql="SELECT * FROM jobs WHERE ".
(!empty($wheres) ? implode(" AND ",$wheres) : '1=1').
";";
What i want to do is add an input in the form
<label for="special">Special Search</label>
<input type="text" name="special" id="special_search">
where the user would be able to search in the case_reference field and get the results that match the first four characters. Also i would like this new input to work the same as the others as far as the AND or OR and TRUE or FALSE statements are concerned.
All help appreciated thank you in advance:)
UPDATE : Instead of rewriting the whole thing i came up with the following code at the begining of my previous :
$joker = $_POST['special'];
$joker1 = substr($joker1, 0, 4);
if(isset($_POST['case_reference']) && !empty($_POST['case_reference'])
&& empty($_POST['special'])) {
} else { $_POST['case_reference'] = $joker1; }
It is working for now but anyone can confirm that it would be okay in future??
From the SQL:
$sql="SELECT * FROM jobs WHERE ". (!empty($wheres) ? implode(" AND ",$wheres) : '1=1').";";
Just simply add a variable for special:
$special = $_POST['special']; // this will get the data from the textbox
then add it to the sql statement
$sql="SELECT * FROM jobs WHERE LIKE $special 'aaaa%' AND ". (!empty($wheres) ? implode(" AND ",$wheres) : '1=1').";";
Rewritten avoiding variable variable names, and using mysql_real_escape_string (although you should use mysqli or pdo):-
<?php
// build array of field names=============================================================================
$fields=array('user','customer','vessel','country',
'port','eta','service_station','type_of_service',
'case_reference','status');
// initialize empty array for WHERE clauses
$wheres = array('1=1');
// loop through field names, get POSTed values,
// and build array of WHERE clauses, excluding false values
foreach ($fields as $field)
{
// get existing field value from POST, mark missing or empty value as FALSE
if (isset($_POST[$field]) && trim($_POST[$field])!='')
{
$wheres[]="`$field`='".mysql_real_escape_string(trim($_POST[$field]))."'";
}
}
if (isset($_POST['special']) && trim($_POST['special'])!='')
{
$wheres[] = " case_reference' LIKE '".mysql_real_escape_string(trim($_POST['special']))."%'";
)
// build SELECT statement from WHERE clauses
$sql="SELECT * FROM jobs WHERE (".implode(" AND ",$wheres).") ;";
?>

$_POST as $key => $value using checkboxes

I am having trouble getting a form to update the information passed from a check box. I was given this code.
$one = isset($_POST['one']) ? 'on' : 'off';
This works great as long as I call each check box separately. My problem is I have approximately 200 checkboxes in total.
Here is the code I am using to UPDATE with. Can anyone help me to figure out where to insert the code I was given into my present code? I've tried all sorts of variations.
if($_POST['submit']){
if(!empty($applicant_id)){
$sql = "UPDATE play SET ";
foreach($_POST as $key => $value){
if(($key != 'submit') && ($key != 'applicant_id')){
$sql .= $key. " = '$value',";
}
}
$sql = substr($sql, 0, -1);
$sql .= " WHERE ".$applicant_id." = $applicant_id";
$result = mysql_query($sql,$db) or die(mysql_error(). "<br />SQL: $sql");
}
}
The solution is to start with your known list of possible checkboxes in an array() or similar. Can I assume you generate the form with such a list? If not, you probably should. Then you can use a loop over the same data to check for the existence of each checkbox.
Some other hints:
isset($array[$key]) is not recommended. Although it will be reliable most of the time, it will fail if $array[$key] is null. The correct call is array_key_exists($key, $array).
When assembling string fragments for SQL, like you're doing, it is more elegant to do the following:
$sqlvalues = array();
foreach( $options as $field ) {
if( array_key_exists('checkbox_'.$field, $_POST) )
$sqlvalues[] = $field.' = \'on\'';
else
$sqlvalues[] = $field.' = \'off\'';
}
mysql_query('UPDATE '.$table.' SET '.implode(', ', $sqlvalues).' WHERE applicant_id = '.$applicant_id);
You may be running to HTML checkbox behavior: Checkboxes are only sent to the server if they are on; if they are off, no name/value pair is sent. You are going to have trouble turning off values with the above code.
So you need to run through your known list of values and check for them in the $_POST parameters.
You should use an array name and it will be an array in PHP.
As ndp said, if a checkbox is unchecked, its value will not be transmitted. So you need to use a hidden input field with the same name before the checkbox input field, with the "off" value.
<label for="one">One</label>
<input type="hidden" name="checkboxes[one]" value="off"/>
<input type="checkbox" name="checkboxes[one]" id="one" value="on"/>
Remember checked="checked" if it should be default to on.
You can now loop the checkboxes with POST or GET
foreach ($_POST['checkboxes'] as $key => $value) {
//something
}
if($_POST['submit']){
if(!empty($applicant_id)){
$sql = "UPDATE play SET ";
foreach($_POST as $key => $value){
if(($key != 'submit') && ($key != 'applicant_id')){
$sql .= $key . " = '" . ($value ? 'on' : 'off') . "',";
}
}
$sql = substr($sql, 0, -1);
$sql .= " WHERE ".$applicant_id." = $applicant_id";
$result = mysql_query($sql,$db) or die(mysql_error(). "<br />SQL: $sql");
}
}
The above assumes that all your inputs are checkboxes. If they aren't, you'll need to work out a convention to distinguish them.
Incidentally, your currently running UPDATE code is vulnerable to SQL injection because you aren't sanitizing your inputs with mysql_real_escape_string(). Cheers.
delete everything above :-)
name all you checkboxes like
and in foreach work with $_POST['out']
BUT! don't forget the golden rule: DOn't belive to the user. re-check every key=>value before writing to the datebase.

Categories