I realize this question has been asked multiple times, but none have resolved the issue for me.
I want to check if any values in the $_POST array are empty except for two (sHostFirstName and sHostLastName), and throw a 400 error if there is an empty value. The only way I can get it to throw the 400 error is by putting a die() command after the header command, however I get the 400 error no matter if there are empty values or not.
foreach ($_POST as $key => $value) {
if (empty($value) || !isset($value) && $key != 'sHostFirstName' || 'sHostLastName') {
header("HTTP/1.1 400 Bad Request");
break;
}
}
isset() will return true if the variable has been initialised. If you have a form field with its name value set to userName, when that form is submitted the value will always be "set", although there may not be any data in it.
Instead, trim() the string and test its length
if("" == trim($_POST['userName'])){
$username = 'Anonymous';
}
There's no need to loop through your POST data. Store your POST data in a variable $postData and remove the keys sHostFirstName and sHostLastName since these two need not be checked.
This $postData contains all key value pairs which need to be checked for blank entries. Now, use array_filter() to filter out any blank entries and store it in $filteredArray.
Finally, if there were no blank entries, the length of $postData will be same as ``$filteredArray`. If lengths don't match, that will imply one or more array keys had been filtered.
$postData = $_POST;
unset($postData['sHostFirstName'], $postData['sHostLastName']); // $postData contanis all key value pairs which can't be empty
$filteredArray = array_filter($postData); // Filters out the blank entries
/* If the length of `$filteredArray` and `$postData` aren't the same, that means one or more fields had been filtered out */
if (count($filteredArray) != count($postData)) {
header("HTTP/1.1 400 Bad Request");
}
Something like this
//store and set default if not set - only needed for checkbox or radio buttons. for example, text fields are always submitted as an empty string.
$sHostFirstName = isset($_POST['sHostFirstName']) ? $_POST['sHostFirstName'] : false;
unset($_POST['sHostFirstName']); //remove so it's not part of our count
//store and set default if not set - only needed for checkbox or radio buttons.
$sHostLastName = isset($_POST['sHostLastName']) ? $_POST['sHostLastName'] : false;
unset($_POST['sHostLastName']); //remove so it's not part of our count
$post = array_filter(array_map('trim', $_POST)); //copy post remove empty items.
if( count( $post ) != count($_POST)
//if count $_POST is not the same as count $post ( empty removed via array_filter) then something was removed / empty
header('HTTP/1.1 400 Bad Request', true, 400);
exit();
}
should do after unset is used on them. See,
store them in variables
remove them from post
then remove empty from a copy of post
count copy ( - empties ) and compare to count of original
if the count is different then something was removed ( ie. empty )
no need for a loop.
Also you can send the optional 2nd and 3rd params for header:
http://php.net/manual/en/function.header.php
2nd = replace - The optional replace parameter indicates whether the header should replace a previous similar header, or add a second header of the same type. By default it will replace, but if you pass in FALSE as the second argument you can force multiple headers of the same type.
3rd = http_response_code - Forces the HTTP response code to the specified value. Note that this parameter only has an effect if the string is not empty.
Related
Code used for processing form $_POST submissions is working well on most forms but suddenly broke on a new set of forms. I can't see any difference in the forms themselves as it's based purely on the posted values and I have it fixed but I am curious why the sudden problem.
There are some cases where specific post values are not to be processed and those, when they are not needed, are in $RemoveFields as a comma-separated list which is converted to an array and on the one set of forms, it doesn't matter if $RemoveFields has any value or not but on the other set it crashes when empty.
By adding a conditional I was able to make it work but can anyone tell me what the problem is on the original code? Both the old and new are below. The first works on only some of the forms while the second seems to work on all.
The original code:
// Remove unneeded fields specified in $RemoveFields variable
if (isset($RemoveFields) && !is_array($RemoveFields)) $RemoveFields = array($RemoveFields);
$filteredarray = array_diff_key($_POST, array_flip($RemoveFields));
The same code but with a conditional for the $filteredarray value:
// Remove unneeded fields specified in $RemoveFields variable
if (isset($RemoveFields) && !is_array($RemoveFields)) $RemoveFields = array($RemoveFields);
$filteredarray = (isset($RemoveFields)) ? array_diff_key($_POST, array_flip($RemoveFields)) : $_POST;
In the original code, you call array_flip($RemoveFields) even when $RemoveFields is not set. This fails because the argument to array_flip() must be an array.
You should use isset() to protect both lines of code:
if (isset($RemoveFields)) {
if (!is_array($RemoveFields)) {
$RemoveFields = array($RemoveFields);
}
$filteredarray = array_diff_key($_POST, array_flip($RemoveFields));
} else {
$filteredarray = $_POST;
}
User gives a input for label and for key too with the other parameters(Key and Label are just example)
I want to add Key to label only once means only at first execution (first button press - but after that on every button click it should not add; php file loads on every button)after that it should be avoided to add (prepend) (key_valuelabel_value)
So my existing code adds key to label but this fails when if user gives label which has value similar to key.
For example:- key='123' and label='123 test' then my condition fails.
So anyone suggest me on this how can I handle this case ?
This is php, everytime it reloads so counter also failed.
I don't asking why do you need that. Hope this code can helps:
function isKeyInLabel($key, $label) {
$keys = explode(' ', $label);
// remove last element (it's a label)
array_pop($keys);
return in_array($key, $keys);
}
usage example:
// this condition will returns true
if (isKeyInLabel('456', '123 456 789 test')) {
// already exists
}
notice: of course you can't use keys or labels with spaces
UPD:
You'll need another variable, for example:
// of course you need a place where you can save this array
// as possible place you can use session or cookies, or
// whatever you want, here is session usage example
session_start();
// this hash will have keys that already executed
$execKeys = isset($_SESSION['execKeys'])?$_SESSION['execKeys']:array();
// assuming that $execKeys[$label] is an array
if (isset($execKeys[$label]) && in_array($key, $execKeys[$label])) {
// code already executed
} else {
$execKeys[$label] = isset($execKeys[$label])?$execKeys[$label]:array();
$execKeys[$label][] = $key;
// and if you still need it
$label = $key.' '.$label;
}
$_SESSION['execKeys'] = $execKeys;
Is it possible to get empty array(array with 0 items) value via $_GET?
Is it possible with direct value setting?
count($_GET['param'])==0
You just need an empty value url = myform.php?param=¶m2=
In form just let the value blank:
<input type='text' name='param' value ='' />
For an empty array:
url: myform.php?param[]=¶m2[some_key]=
in form: <input type='text' name='param[]' value ='' />
From Ajax: (I remember this was so anti-intuitive and hard to search for):
ajax{
...
data: {'params[]':'','params2[some_key]':''}
}
Workaround:
Just edit the back-end and if there is no data for params or it is not an array (null, empty whatever ..) just assign an empty string to it:
$param = (isset($_GET['param']) && is_array($_GET['param']))? $_GET['param'] : array();
Update:
I did few tests and it seems there is no way to put "nothing" in the request ussing a form or ajax.
0, '', Null are valid values for the $_GET but empty array is not even created.
So to answer your question, it is NOT possible to get empty array value from the front-end.
There are few options to edit $_GET manually in the back-end:
<?php
if(!isset($_GET['param']) || !$_GET['param']){ //not set or (null,0,"")
$_GET['param'] = array();
}
if(count($_GET['param'])==0){...}; // 0 if no 'param' was provided.
If array is empty or containing values that doesn't matters. Just declare a variable and pass the $_GET[] to the variable.
for example,
$para=$_GET['param'];
and now
if(is_array($para))
{
//
}
else{
$para=new array();
}
passing empty array via GET is not possible under normal situation. That said, I can think of a really rare way that the checking you used will return true.
http://domain.com/receiver?param=a%3A0%3A%7B%7D
The above is basically a serialized and urlencoded empty array with the key 'param'
if the target server have some sort of filter that auto unserialize all incoming data, then it might happen.
(or something like the below)
foreach($_GET as $key => $value){
$_GET[$key] = unserialize($value);
}
count($_GET['param'])==0
I know this is a far fetch but it is possible, maybe some private test server that only handles serialized data but accidentally open to public e.t.c.
That said, it is still only passing a serialized empty array instead of a empty array itself. But let's be honest, this answer is more like a joke/fun answer that tries to point out under some very rare case
count($_GET['param'])==0
will return true (Without actively assigning values # server side)
This is honestly the most finicky and inept language I've ever coded in. I'll be glad when this project is good and over with.
In any case I have to us PHP so here's my question.
I have an Array named $form_data as such:
$form_data = array
('trav_emer_med_insur',
'trav_emer_single',
'trav_emer_single_date_go',
'trav_emer_single_date_ba',
'trav_emer_annual',
'trav_emer_annual_date_go',
'trav_emer_extend',
'trav_emer_extend_date_go',
'trav_emer_extend_date_ef',
'trav_emer_extend_date_ba',
'allinc_insur',
'allinc_insur_opt1',
'allinc_single_date_go',
'allinc_single_date_ba',
'allinc_insur_opt2',
'allinc_annual_date_go',
'allinc_annual_date_ba',
'cancel_insur',
'allinc_annual_date_go',
'allinc_annual_date_ba',
'visitor_insur',
'country_select',
'visitor_supervisa',
'visitor_supervisa_date_go',
'visitor_supervisa_date_ba',
'visitor_student',
'visitor_student_date_go',
'visitor_student_date_ba',
'visitor_xpat',
'visitor_xpat_date_go',
'visitor_xpat_date_ba',
'txtApp1Name',
'txtApp2Name',
'txtApp1DOB',
'txtApp2DOB',
'txtApp1Add',
'txtApp1City',
'selprov',
'txtApp1Postal',
'txtApp1Phone',
'txtApp1Ext',
'txtApp1Email',
'conpref', );
These are the names of name="" fields on an HTML form. I have verified that ALL names exist and have a default value of '' using var_dump($_POST).
What I want to do is very simple, using the $form_data as reference do this:
create a new array called $out_data which can handle the data to display on a regurgitated form.
The structure of $out_data is simple the key will be the name of the element from the other array $out_data[txtApp1Name] for example, and then the value of that key will be the value.
Now what I want is to first check to see if every name="" is set or not, to eliminate errors and verify the data. Then regardless of whether it is set or not, create its placeholder in the $out_data array.
So if $_POST[$form_data[1]] (name is 'trav_emer_single') is not set create an entry in $out_data that looks like this $out_data([trav_emer_single] => "NO DATA")
If $_POST[$form_data[1]] (name is 'trav_emer_single') is set create and entry in $out_data that looks like this: $out_data([trav_emer_single] => "whatever the user typed in")
I have tried this code:
$out_data = array();
$count = count($form_data);
for( $i = 0; $i < $count; $i++ )
{
if(!isset($_POST[$form_data[$i]])) {
$out_data[$form_data[$i]] = "NO_DATA";
}
else {
$out_data[$form_data[$i]] = $_POST[$form_data[$i]];
}
}
Now this code technically is working, it is going through the array and assigning values, but it is not doing so properly.
I have hit submit on the form with NOTHING entered. Therefore every item should say "NO_DATA" on my regurgitated output (for user review), however only some items are saying it. All items I have confirmed have name="" and match the array, and have nothing entered in them. Why is "NO_DATA" not being assigned to every item in the array?
Also of note, if I fill in the form completely $out_data is fully and correctly populated. What is the problem with !isset? I've tried doing $_POST[$form_data[$i]] == '' which does put no_data in every instance of no data, however it throws an 'undefined index' warning for every single item on the page whether I write something in the box or not.
Really I just want to know WTF is going on, the dead line for this project is closing fast and EVERY step of the PHP gives me grief.
As far as I can tell by reading around my code is valid, but refuses to execute as advertised.
If you need more code samples please ask.
Really befuddled here, nothing works without an error, help please.
Thanks
-Sean
Instead of checking !isset(), use empty(). If the form posts an empty string, it will still show up in the $_POST as an empty string, and isset() would return TRUE.
I've replaced your incremental for loop with a foreach loop, which is almost always used in PHP for iterating an array.
$out_data = array();
foreach ($form_data as $key) {
if(empty($_POST[$key])) {
$out_data[$key] = "NO_DATA";
}
else {
$out_data[$key] = $_POST[$key];
}
}
PHP's isset returns TRUE unless the variable is undefined or it is NULL. The empty string "" does not cause it to return FALSE. empty() will do exactly what you need, though.
http://php.net/manual/en/function.isset.php
isset() will return FALSE if testing a variable that has been set to
NULL. Also note that a NULL byte ("\0") is not equivalent to the PHP
NULL constant.
Returns TRUE if var exists and has value other than NULL, FALSE
otherwise.
I have a form that allows the user to add information an their leisure. They can add locations via jQuery in my form so when recieving the data I may have 1 location or 10. Each location has attributes like phone, address, etc. In my form the input names are appended with _1 , _2, etc to show its a new set of data. That is working swimmingly and I just can't seem to find these keys when looping through the $_POST array
private function array_pluck($arr,$text)
{
foreach($arr as $key => $item)
{
if(stripos($key,$text) != 0)
{
$found[] = $item;
}
}
return $found;
}
As I understand it if my array has some keys "office_branch_phone_1, office_branch_phone_2" I should be able to put in "office_branch" in my $text param and it will spit out any keys with the "office_branch" in the name. This isn't working however and I'm a bit stumped.
Since stripos will return the index (and it is a 0-based index returned) != 0 is incorrect.
if (stripos($key,$text) !== false)
Would be the correct way to check it. Give that a shot.
EDIT
Note the use of !== instead of != since 0 tends to be considered false if loosely checked the !== will check the actual type, so 0 is a valid return. Just an extra tidbit of information