PHP Form Validation Issue - Validate Large Set of Input Fields - php

I have 20 "sets" of input fields in my HTML Form.
Here is a taster:
<input id="a1height" />
<input id="a1width" />
<input id="a1length" />
<input id="a1weight" />
<input id="a2height" />
<input id="a2width" />
<input id="a2length" />
<input id="a2weight" />
...and so on
Now, I need a way of:
a) storing all the values in one variable with pipes(|) between the height, width, length & weight and \n between each set
b) if one or more of the fields in a set is incomplete my variable $errors is set to true.
I'm at a little bit of a loss on how I can achieve this. Never really good with loops :'(
Can someone explain how to do this?
Many thanks!!

Here is a solution using an $errors array that stores all errors and an $all string that contains your desired output. To check, put var_dump( $all); at the end of the script.
$errors = array();
$all = '';
// Loop over the values 1 through 20
foreach( range( 1, 20) as $i)
{
// Create an array that stores all of the values for the current number
$values = array(
'a' . $i . 'height' => $_POST['a' . $i . 'height'],
'a' . $i . 'width' => $_POST['a' . $i . 'width'],
'a' . $i . 'length' => $_POST['a' . $i . 'length'],
'a' . $i . 'weight' => $_POST['a' . $i . 'weight']
);
// Make sure at least one submitted value is valid, if not, skip these entirely
if( count( array_filter( array_map( 'is_numeric', $values))))
{
// This basically checks if there's at least one numeric entry for the current $i
continue; // Skip
}
// Validate every value
foreach( $values as $key => $value)
{
if( empty( $value))
{
$errors[] = "Value $key is not set";
}
// You can add more validation in here, such as:
if( !is_numeric( $value))
{
$errors[] = "Value $key contains an invalid value '$value'";
}
}
// Join all of the values together to produce the desired output
$all .= implode( '|', $values) . "\n";
}
To nicely format the errors, try something like this:
// If there are errors
if( count( $errors) > 0)
{
echo '<div class="errors">';
// If there is only one, just print the only message
if( count( $errors) == 1)
{
echo $errors[0];
}
// Otherwise format them into an unordered list
else
{
echo '<ul>';
echo '<li>' . implode( '</li><li>', $errors) . '</li>';
echo '</ul>';
}
echo '</div>';
}

First should create NAME properties for your inputs, as these will be used in the _POST array to specify your values.
<input id="a1height" name="a1height" />
<input id="a1width" name="a1width" />
<input id="a1length" name="a1length" />
<input id="a1weight" name="a1weight" />
<input id="a2height" name="a2height" />
<input id="a2width" name="a2width" />
<input id="a2length" name="a2length" />
<input id="a2weight" name="a2weight" />
Then, after you submit, loop through the post array creating your pipe-joined varibles
$errors = false;
$string = "";
$current_prefix = '';
foreach($_POST as $key=>$posted_value){
if(trim($posted_value)==""){ //if the value is empty or just spaces
$errors = TRUE;
}
//find out if we need to add a new line
$number = preg_replace ('/[^\d]/', '', $key) //get the numbers of the name only
if ($current_prefix != $number){
$string .= "\n";
} else {
$string .= '|';
}
$string .= $posted_value;
}

Create an array to store your values.
Loop through your input fields, parsing the prefix (ie 'a1') from the field type (ie 'height')
Insert the values into the array like this:
$your_array['a1']['height'] = $_POST['a1height'];
Remember to validate and sanitize your input.

You can change your html so the posted fields come in a nicely formatted array:
<input name="a1[height]" />
<input name="a1[width]" />
<input name="a1[length]" />
<input name="a1[weight]" />
<input name="a2[height]" />
<input name="a2[width]" />
<input name="a2[length]" />
<input name="a2[weight]" />
That way you get an array that's easy to use. You could access $_POST['a1']['height'] or $_POST['a1']['length'] or $_POST['a2']['height'].

Related

Print out the index of all occurrences of a string in an array

I have created a simple PHP script where the user types in a sentence (or sentences) and the script takes each word from the textarea and splits it up into an array. The user will also type in a word to search for in the array.
The script should look through the array and print out the index of all places where the word is.
This is what I have so far:
foreach($parts as $item) {
if ($item == $strName) {
$k = array_search($strName, array_values($parts));
print "$k\n";
}
}
However that only prints out the first index location of the string. So if the sentence I use is "The apple fell from the tree", it will just print out "0 0", which is the first time the word appears in the array (it also does the same if the index is 1, 2, 3, etc). Is there something that I have done wrong? Sorry if I didn't include enough information.
Entire code:
<form action="sida3.php" method="post">
Text: <textarea name="textarea"></textarea>
<br>
Search word: <input type="text" name="search">
<br>
<input type="submit" name="submit" value="Submit">
</form>
<?php
if(isset($_POST['submit'])){
$parts = explode(" ", $_POST['textarea']);
$strName = $_POST['search'];
print_r ($parts);
echo '<br>';
foreach($parts as $item) {
if ($item == $strName) {
print_r(array_keys($parts, $strName));
}
}
}
?>
Here you go
function search_array( $needle, $string ){
$haystack = explode( " ", $string);
$keys_found = array_keys( array_map( "strtolower", $haystack) , strtolower( $needle ), false);
if( !empty( $keys_found ) ):
return array(
"count" => count( $keys_found ),
"keys" => $keys_found
);
else:
return false;
endif;
}
var_dump( search_array("Every","Every good boy does fine, every good girl does fine") );

how to validate "provide at least 2 tags, separated by commas" from tag textfield in php?

HTML
<h3>Tags</h3>
<input <?php echo $err_st3; ?> type="text" name="tags" id="textfield"
placeholder="Example: tag, another tag, hello tagging" value="
<?php echo #$tagsOK; ?>">
Php
$tags=array();
$tagline = $_POST['tags'];
//TAGS
if(!empty($tagline)){
$tokens = str_replace(' ', '', $tagline);
$tags = explode(',',$tokens);
$tags = array_unique($tags);
foreach ($tags as $tag) {
if(preg_match("/^[0-9a-zA-Z]$/",$tag) === 0) {
// error
}
else{
echo $count_tags = $count_tags+1;
}
}
if($count_tags <= 1){
$error[]=" - Please provide at least 2 tags, separated by commas.";
$err_st3 = $st;
}
$tagsOK = implode(', ',$tags);
}
else{
$error[]=" - Please provide at least 2 tags, separated by commas.";
$err_st3 = $st;
}
When I enter the letters like "a, b", then it will be valid.
But it does not validate words like "vehicle, characters, scene"
Instead of doing preg_match check length:
strlen($tag)==1

PHP - Comparison of array element to input issue

I'm having an issue with the code below, I want to test a user's input against values in a text file. The output of the code works only for the last element of the array (each value of the text file is stored as an element of an array) which succeeds in correctly comparing the input against the array element, however when entering any other element in the array, no 'match' is being made. I want all values to be numeric and only one same value to exist, if more than one, output an error. Thanks guys :)
array.txt has the following contents
11111
22222
33333
44444
PHP:
<?PHP
if (isset($_REQUEST['attempt'])) {
$users = file('C:/wamp/www/php/comparision/array.txt');
$input = $_POST['input'];
print "Results:";
print '<br></br>';
$x = count($users);
print '<br></br>';
print '<br></br>';
$i = 0;
while ($i < $x) {
print $users[$i];
print $input;
$truevar = NULL;
$arrayelement = $users[$i];
if ($input == $arrayelement) {
print '<p>';
echo " It is in the array";
print '</p>';
$truevar = $truevar + 1;
}
else if ($input != $arrayelement) {
print '<p>';
echo " Nope";
print '<p>';
}
print '<br></br>';
$i = $i + 1;
}
//Check entries
if ($truevar > 1) {
print '<br></br>';
echo "Multiple entries";
}
else if ($truevar == 1) {
print '<br></br>';
echo "Comparison success";
}
else if ($truevar < 1) {
print '<br></br>';
echo "Comparison not successfull";
}
}
?>
<p>Please enter data</p><br></br>
<form action="compare.php?attempt" method="post"/>
<input type="text" name="input" size="15" value="" />
<input type="submit" name="carddata" value="Submit"/>
</form>
Use:
$users = file('C:/wamp/www/php/comparision/array.txt', FILE_IGNORE_NEW_LINES);
Without that option, the newlines that separate the lines in the file are included in the values in $users, so the comparisons fail.
The problem seems that you set $truevar = NULL; inside the while loop. Like this, the variable always gets reset to NULL with every loop.
You should be fine if you move the $truevar = NULL above the while-line

Search instead filename

I have this script to search file into a directory.
Works well when i perform search with exactly term, example: "my file.doc", "sales order 1234.pdf"
Can anyone help me to modify to search word into filename, example: "file" ou "Sales"
TKS
Cris.
<?php
if($_POST['search']) {
$word = $_POST['file'];
$dir = './';
$list = new RecursiveDirectoryIterator($dir);
$recursive = new RecursiveIteratorIterator($list);
$num = 0; //
foreach($recursive as $obj){
//echo $obj->getFilename().'<br />';
if($obj->getFilename()=="$word"){
echo $obj->getPathname().'<br/>';
$num++;
}
}
echo "found(s) $num file(s).";
}
?>
<form action="" method="POST">
search files. <input type="text" name="file" value="">
<input type="submit" name="search">
</form>
<?php
if($_POST['search']) {
$word = $_POST['file'];
$dir = './';
$list = new RecursiveDirectoryIterator($dir);
$recursive = new RecursiveIteratorIterator($list);
$num = 0; //
foreach($recursive as $obj){
//echo $obj->getFilename().'<br />';
if( strpos( $obj->getFilename(), "$word" ) === true ){
echo $obj->getPathname().'<br/>';
$num++;
}
}
echo "found(s) $num file(s).";
}
?>
<form action="" method="POST">
search files. <input type="text" name="file" value="">
<input type="submit" name="search">
</form>
You can use the strpos function or the strstr function on your filename.
Test if the function returns something different than false to know your filename contains your chain.
You can use PHP's substr_count to count the occurrences of a string in another, but since you need one or more you can check like this:
if( substr_count( $obj->getFilename(), $word ) ){
echo $obj->getPathname().'<br/>';
$num++;
}
edit: for case-insensitive comparison:
if( substr_count( strtolower($obj->getFilename()), strtolower($word) ) {
// ...
}

PHP post checkboxes help

I"m having trouble receiving a list of items that are checked in a field of checkboxes which are part of a form.
I have an HTML table with a few checkboxes:
HTML
<input type="checkbox" name="carry[]" value="1" />
<input type="checkbox" name="carry[]" value="2" />
<input type="checkbox" name="carry[]" value="3" />
PHP - this is what I'm using to post the form to an email address
foreach($_POST as $key => $val) {
$body .= $key . " : " . $val . "\r\n";
I get the value in my email as: "carry: Array" -- not the actual values that are selected. How do I handle an array of checkboxes selected in a form and post it?
Ideally, I would want: "carry: 1; 2; 3" (without the quotes)
You can check if the value is an array and handle it differently:
foreach($_POST as $key => $val) {
if (is_array($val)) {
$body .= $key . " : " . implode(",",$val) . "\r\n";
} else {
$body .= $key . " : " . $val . "\r\n";
}
}
If you want the string '1; 2; 3', you should join together the items in the array:
$carry= implode('; ', $_POST['carry']);
However doing so will naturally cause ambiguous results if any of the items in the array themselves have a semicolon in.
To iterate over the post array allowing any of its members to be arrays:
foreach($_POST as $key=>$val) {
if (is_array($val))
$val= implode('; ', $val);
$body.= "$key: $val\r\n";
}
Or, if you don't need so much control over the exact formatting and a debugging dump is fine (but you need to see more than just the useless string 'Array':
$body= var_export($_POST, TRUE);
It's printing carry: Array because that's exactly what it is. You need to loop over it (another loop inside the first) to access the values inside:
foreach($_POST as $key => $val) {
if($key == 'carry') {
foreach($val as $carry) {
$body .= $carry;
}
}
else {
$body .= $key . " : " . $val . "\r\n";
}
}
That's completely untested but hopefully the logic is sound :)

Categories