PHP sanitizing location data - php

I've got this html
<select name="country">
<option value="Iraq">1</option>
<option value="Texas">2</option>
<option value="Paris">3</option>
...
<option value="n">nnn</option>
</select>
There are a really hellish lot of options in this select element and I wouldn't really like to allow people to change the values of any options and I can't stop them from doing that, though, I am curious, is there an efficient PHP way to check if the value legit, for example, I could do this:
<?php
$country = $_POST['country'];
if(($country == "Iraq") && ($country == "Texas") && ($country == "Paris) ....($country == "n"))
{
allow stuff;
}
?>
But that would require a really huge amount of if statements, isn't there another magical way to solve this problem?

Sure, use in_array:
$countries = ['Iraq','Texas',...];
if(in_array($_POST['country'], $countries)) {
// allow stuff
}
Build your $countries array once, and then use it to generate your <select> HTML code and to validate the submission. Bonus!
Side note: I need to visit the country of Texas. Didn't realize they seceded!

This is far from magic but one (somewhat efficient) way to check would be to use in_array
http://php.net/manual/en/function.in-array.php
Once you have an array of your countries, you can also use it to generate the drop down.

Related

Insert a .txt document into a select drop down?

I'm not sure if this is the best way of doing this or if it is even possible however what I'm trying to achieve is to echo out all these countries as a list in a select dropdown here is the list Country text document
So my question is how would I display these in a select dropdown or if I can't do this the way I'm trying to do it what would be the best way of doing it without manually adding each country to the form?
<select>
<option value="GB: United Kingdom">GB: United Kingdom</option>
<option value="etc">etc</option>
<option value="etc">etc</option>
<option value="etc">etc</option>
</select>
Remark: The .txt document mentioned in the question contains the list of world countries. It is a list with fixed content; it doesn't change during the execution of the program, it doesn't change between different executions of the program. It changes sometimes, not very often, when an entry is added or removed from the list. More often, the code or the name of existing items change.
This answer is tailored to the content of the file. It is not a recipe good for all situations.
The best way (given the content of the file you want to load) is to have the list of country names indexed by country code in the PHP code, in a separate file.
Something like this (file listCountries.php):
<?php
// ISO-3166 country codes
return array(
'AF' => 'Afghanistan',
'AX' => 'Åland Islands',
'AL' => 'Albania',
// ...
);
// This is the end of file; there is no need for a PHP close tag
When you need to use it, all you have to do is to write something like this:
$listCountries = include 'listCountries.php`;
Of course, you should put it somewhere in a directory of included files and take care of the path in the include line.
You can then iterate over $listCountries and generate the HTML code you need:
<select>
<?php
// Assuming the country with code $selectedCode have to be already selected in the list
foreach ($listCountries as $code => $name) {
$selected = ($code == $selectedCode) ? ' selected="selected"' : '';
echo('<option value="'.$code.'"'.$selected.'>'.htmlspecialchars($name)."</option>\n");
}
?>
</select>
You can generate the file using search and replace in your editor (if it knows search and replace with regular expressions) or you can write a little PHP script to generate the list for you:
$listCountries = array();
$fh = fopen('http://www.textfixer.com/resources/dropdowns/country-list-iso-codes.txt', 'r');
while (! feof($fh)) {
list($code, $name) = fgetcsv($fh, 0, ':');
$listCountries[$code] = $name;
}
fclose($fh);
echo("<?php\n");
echo('$listCountries = ');
var_export($listCountries);
echo(";\n");
echo("// That's all, folks!\n");
Run it using the PHP command line and it will dump the PHP code of the list to the output. You can either redirect its output to a file or change it to write the code into a file (the first option is easier).
You can read more about the ISO-3166 country codes on Wikipedia or you can get the up to date information directly from the authoritative source: the ISO.
A simple example which certainly needs more love:
<?php
$fh = fopen('list.text', 'r');
?>
<select>
<?php
while ($line = fgets($fh, 1024)) {
echo sprintf(' <option value="%1$s">%1$s</option>'."\n", trim($line));
}
?>
</select>
The output obviously is:
<select>
<option value="AF:Afghanistan">AF:Afghanistan</option>
<option value="AX:Åland Islands">AX:Åland Islands</option>
.....
</select>
The short answer is yes it is possible, but is it the best way? No, it isn't, there are many other better ways than plain text storage.
If you ask for advice I would tell you to do it from a DB table or from a JSON, even from a XML.
If you are going to change your mind and use one of these methods I recommend you to google it (You can find the structure that suits your application).
Any way as a guidance I have used these two recently:
DB Script format
JSON format
Right now in my case I'm using a JSON format.
To access and populate the select you can use javascript, more in particular JQuery would be handy, like this:
$.getJSON( "test.json", function( data ) {
var items = [];
$.each( data, function( key, val ) {
items.push( "<option value='" + key + "'>" + val + "</option>" );
});
});
For further information check the official manual.
If you prefer to populate your dropdown on the server you could do something like this:
$json = file_get_contents('your_json_url');
$countries = json_decode($json);
foreach ($countries as $option){
echo "<option value='" .$option[key]. "'>" .$option[$value]. "</option>";
}
If you want to do it from your databese the proccess is really similar as long as you also get an array.
If you still want to keep using your .txt format the #arkascha and #axiac answers are totally valid.
Hope this helped you ;)

Best way to handle a range on inputs on a drop down select input?

I'm working on a project where I have a drop down menu that has a range of values as follows:
<select name="value">
<option value="00000000100">0-100</option>
<option value="00100001000">100-1000</option>
<option value="01000010000">1000-10000</option>
<option value="10000100000">10,000</option>
</select>
This select is part a of a form, that once submitted is going to look for values in a database between the given numbers.
I notice there are a lot of sites that have menus like this, but upon doing some searching, I was unable to find any good descriptions on how to do this.
So, I came up with the above idea to pass the above data, and then do something like this to get my values:
$string = $_POST['value']
$min = substr($string, 0, 5);
$max = substr($string, 5);
Then, I can use my values obtained there in my queries.
My question: is there a better way? This way forces me to add extra markup in my selects, which I don't think is going to cause any issues, but I would still like to know if there is an "accepted" way to achieve the same results. Maybe I was using the wrong terms, but I simply couldn't find anything in a similar vein to what I wanted to achieve.
Not sure about a "best" way, but if you use the 0-100 style then just:
list($min, $max) = explode('-', $_POST['value']);
For the 10,000 option, 10,000 will be the $min and $max will not exist.
I would use an array to store the data and on the select just keys to the array.
This way the user won't be able to inject and change the data being posted and you can easily use it.
Setup your ranges:
$data = array(1=>array(0,100), 2=>array(101,1000), 3=>array(1000,10000), 4=>array(10000,1000000));
The HTML:
<select name="value">
<option value="1">0-100</option>
<option value="2">100-1000</option>
<option value="3">1000-10000</option>
<option value="4">10,000+</option>
</select>
The receiving page:
if (isset($_POST['value'], $data[$_POST['value']])) {
$min = $data[$_POST['value']][0];
$max = $data[$_POST['value']][1];
} else {
//valid range not submitted
}
© Prix

Remembering php form data to display currency all over a website

I've set up a currency conversion dropdown in a wordpress site.
The only thing missing is that every time I load another page, the currency will reset as the form selection was 'forgotten'.
Any ideas how to do this? I tried a suggested js cookie that I saw here, but it doesn't work.
This is what I got so far:
<form name="myform" id ="myform" method="post">
<select name="currency-select" id="sort" onchange="submitform();">
<option value="" selected="selected">Currency</option>
<option value="0">U.S Dollars (USD)</option>
<option value="1">Euros (EUR)</option>
<option value="2">British Pounds (GBP)</option> `
</select>
</form>
js:
function submitform()
{
document.myform.submit();
}
I tried using this code as recommended here but it doesn't really work out for me, I think I didn't do it the right way -
<?php
`session_start();`
if (isset($_POST['currency-select'])) {
$_SESSION['sort'] = $_POST['sort'];
}
?>
I added the $_SESSION to the form as well:
<option value="0" <?php if($_SESSION['sort'] == "0") echo "selected";?>>U.S Dollars (USD)</option>
UPDATE
I've made a few tests. The session seems to be saved (as I echoed it on a few pages while refreshing etc.) I guess the only problem now is related to the form itself. Even with the right session number, I can't get it to select the right option.
I've tried two methods, but both does not work:
<option value="0" <?php if($_SESSION['currency-select'] == "0") echo 'selected="selected"';?>>U.S Dollars (USD)</option>
or
<option value="0" <?php if($_SESSION['currency-select'] == "0") echo "selected";?>>U.S Dollars (USD)</option>
I'd store the selected value in a $_SESSION['selected_currency'] variable and the cross check and select it when the drop down is being populated with the currency list.
Assuming that the sessions are working, I will use something like below to keep the currency selected in your drop down.
<select name="currency">
<?php
foreach($currency as $value){
if($value->currency_code == $_SESSION['currency']){
echo "<option value='$value->currency_code' selected='selected'>$value->currency_name</option>";
} else {
echo "<option value='$value->currency_code'>$value->currency_name</option>";
}
}
?>
</select>
There could be shorter ways, I am using this for illustration purposes.
For permanent retain of data you only have a few possibilities, the easiest to implement are $_SESSION, $_COOKIE or in a Database.
You have two options to do that
1st is by adding a field to the options.php page and save your data then get back your data from the options.php for that you've to use update_option('nameOfField_form','nameOfFieldDb'); and get_option('nameOfFieldDb').
and 2nd option is by jquery.ajax(); method save your data in options.php
you may find these links helpful codex
get_option
update_option

Language - automatic and by user

I´m trying to play around with languages and an own Database/CMS structure. I´ve got so far, that the Browserset language is selected. This works well. I know there are better solutions (other domains for each language, i´ve google´d a lot)...with an own added cookie (setcookie) it worked, too.
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
$langCookie = $_COOKIE['language'];
if(!empty($langCookie)){
$lang = $_COOKIE['language'];
}
if($lang == en){
//Select from database, got three languages, text (en), textOther1 (otherlang1) and textOther2
}elseif($lang == xy){
//other selecet
}else{
//select if nothing fits
}
My problem at this point is:
How can I let the user choose a language with a select on the page. I want to let the user choose the language by a select...but i can´t get it done to set my cookie as I selected an option...
I know that I have got to reload the page after this (header_location), but I can´t get further...
Any help or tipps for solving this would be very nice.
I think you can use the GET method to sent request to a page, just add the language code as a paramter, then check whether this parameter exists -- if not, take your value as it's now.
You can use this markup for example:
<form id="langForm" action="" method="GET">
<select name="lang" onchange="this.form.submit();">
<option value="en">English</option>
<option value="fr">French</option>
</select>
</form>
Then on-server side you should check if lang parameter exists:
<?php
if( isset( $_GET ) && ! empty( $_GET['lang'] ) ) {
// do something
} else {
// do something else
}
?>
Hope that helps!

mysql update query with form array

Multiple posts but I'm still stuck...I'm missing something fundamental here. I have a form with a select:
<select name="camera_status[]">
<option <?php echo $enabled_option; ?>>Enabled</option>
<option <?php echo $disabled_option; ?>>Disabled</option>
</select>
This form is built with a loop to give a list of all camera settings. So you would have multiple cameras and their corresponding camera_status. Also I have a hidden input field with the camera_id:
The camera_id is processed with some javascript. Then I process that with:
$camera_id = $_POST['camera_id'];
if (is_array($_POST['camera_status']))
{
foreach ($_POST['camera_status'] as $camera_status) {
$query_status = 'UPDATE `#__cameras` SET `camera_status` ="'.$camera_status.'" WHERE `camera_id`='.$camera_id;
$db->setQuery($query_status);
$db->query();
}
}
If I echo the camera_id it is correct. But my foreach runs an update query for the full list of cameras instead of just the one selected. So it updates only the last camera in the list. Let me know if it makes sense to update the full code. Obviously I'm going about this all wrong...
EDIT: Well if you have single selection then it is simpler than that:
HTML:
<select name="camera_status">
<option value="Enabled">Enabled</option>
<option value="Disabled">Disabled</option>
</select>
And PHP:
$camera_id = (int) $_POST['camera_id']; //Here you had SQL injection.
$camera_status = mysql_real_escape_string($_POST['camera_status']); //Neither that was protected.
$query_status = 'UPDATE `#__cameras` SET `camera_status` ="'.$camera_status.'" WHERE `camera_id`='.$camera_id;
$db->setQuery($query_status);
$db->query();
You have a fundamental flaw in your thought process for the page. When you output more than one <select name="camera_status[]"> elements, you're going to get that many results back. With two of them, you'll get two values in the array, and so on.
What it sounds like you're doing is outputting a list of cameras, having the user select a camera to modify, and then, from then on, all of the camera settings now only apply to that one specific camera. If this is the case, then you don't need to use arrays for the camera settings, including camera_status. Just remove the array portion and stop outputting more than one HTML element for each camera setting (since you know that once a camera is selected, those values apply to that specific camera).
However, if your page that displays the multiple cameras allows the user to modify every camera and its settings, you'll need to accommodate for the user's input.
If the latter is the case, here's a neat trick - Modify your <select> so it looks like this when you're outputting your camera form:
<select name="camera_status[<?php echo $row['camera_id']; ?>]">
<option value="1">Enabled</option>
<option value="0">Disabled</option>
</select>
Now, when you grab $_POST['camera_status'], it'll be an array with the camera IDs as the keys and their selected value as the value. So now, you can do this:
if( is_array($_POST['camera_status']))
{
foreach ($_POST['camera_status'] as $camera_id => $camera_status) {
$camera_status = intval( $camera_status); // Be wary of SQL injection
$camera_id = intval( $camera_id);
$query_status = 'UPDATE `#__cameras` SET `camera_status` ="'.$camera_status.'" WHERE `camera_id`='.$camera_id;
$db->setQuery($query_status);
$db->query();
}
}
Now this will update every camera with the correct value chosen.
Easy enough. Add value attributes to the <option> tags so that each of them will have a value
<select name="camera_status">
<option value="1" <?php echo $enabled_option; ?>>Enabled</option>
<option value="0" <?php echo $disabled_option; ?>>Disabled</option>
</select>
Then, in your php, look for that value
foreach ($_POST['camera_status'] as $camera_status) {
if($camera_status == 1) {
$query_status = 'UPDATE `#__cameras` SET `camera_status` ="'.$camera_status.'" WHERE `camera_id`='.$camera_id;
$db->setQuery($query_status);
$db->query();
}
}

Categories