PHP Validation Using An Regex Array - php

I am working on creating an array of regular expressions based on form values and using a function that fails on the wrong user input. Every time I run the website I receive the following error:
Warning: eregi() [function.eregi]: REG_EMPTY
I do not know what is wrong. Please take a look at my code and help. Thank you!
$error_log = array();
// Checks if user inputed data matches the default values
$arr = array(
'name' => 'First Name Last Name',
'month' => 'MM',
'day' => 'DD',
'year' => 'YYYY',
'address1' =>'Address Line 1',
'address2' => 'Address Line 2',
'email' => 'John#myemail.com'
);
$regex = array(
'name' => "^[a-z .'-]+$",
'month' => "^((0[1-9])|(1[0-2]))$ ",
'day' => "0?[1-9]|[1-2][0-9]|3[0-1]",
'year' => "^(19|20)\d{2}$",
'address1' => "/^[a-zA-Z0-9 ]*$/",
'address2' => "/^[a-zA-Z0-9 ]*$/",
'email' => "^[A-Z0-9._%-]+#[A-Z0-9.-]+\.[A-Z]{2,4}$"
);
/*
Runs validation on the form values and stops procesing if the form does not have the correct values
*/
function regexValidate( $form_value, $regex, $key){
if(!eregi($regex[$key],$form_value) ){
return true;
}
return false;
}

I have a slightly different approach. I have an array such as this - which I ultimatley pass to Smarty to build my for - but upon submission, this array is passed witht he form $_POST into a function that loops round and does the necessary validation (based on the 2nd parameter here);
$arrFields = array(
'stage1' => array(
'accountname' => array('Account Name','text','text','stage1',true),
'presharedaccountkey' => array('Pre-shared Key','text','text','stage1',true),
'ipwhitelist' => array('IP White-list','text','text','stage1',false),
'accountid' => array('Customer ID','text','readonly','stage1',false),
'product' => array('Product','text','select','stage1',false,$platformProducts),
'dtcreated' => array('Created on','text','text','stage1',false),
'createdby' => array('Created By','text','text','stage1',false),
'mode' => array('Mode','text','radio','stage1',true,$platformModes)
)
);
i do some custom stuff but basically to loop it'd be:
function validateFormPost($arrFields,$postfields)
{
$err = array();
//validate required fields
foreach($arrFields as $stagekey => $stageval)
{
foreach($stageval as $key => $val)
{
// your validation based on field type
// i.e. in here would be regex to deal with std type or indeed you could add it as a parameter to the $arrFields construct.
// allow comma or spaced emails but replace with semi colon
if($val[1]=='email')
{
$postfields[$key] = str_replace(",",";",trim($postfields[$key]));
$postfields[$key] = str_replace(" ",";",trim($postfields[$key]));
}
// basic check required fileds are completed
if($val[4]==true && !array_key_exists($key,$postfields))
{
$err[$stagekey][$key] = array($val[0],'This is a required field');
}
elseif(array_key_exists($key,$postfields) && $this->validateField($postfields[$key],$val[1],$val[4])==false)
{
$err[$stagekey][$key] = array($val[0],'Invalid '.$val[1].' value.');
//check values for basic field length
}
elseif(strlen($postfields[$key])>$feildcolset[$key][0] && $feildcolset[$key][0]!=null)
{
$err[$stagekey][$key] = array($val[0],'Field max '.$feildcolset[$key][0].' characters.');
}
}
}
}
HTH - i can expand on it if needed :)

Related

Check if array contains array matching a value then store result into new array

I have an odd question which I cannot find an answer to on Google or SO.
I have an array containing all the bits of information about the pages on my website. So the array contains multiple of the arrays like the example below:
'home' =>
array (size=7)
'title' => string '' (length=0)
'url' => string 'home.php' (length=8)
'mobile' => string 'home.php' (length=8)
'keywords' => string '' (length=0)
'description' => string 'test123' (length=126)
'login_needed' => boolean false
'original_page' => string 'home' (length=4)
What I need to do is to find each array that contains a value that comes from a search bar. For example if the user searches for "bruidsmode" every array that contains "bruidsmode" should be put into another array which I can then output into elements to display on the website.
Below you will find a stripped example of what I have on my page. (I tried making a working example but was unable to do so):
<?php
$config['menu']["home"] = array (
'title' => '',
'url' => 'home.php',
'mobile' => 'home.php',
'keywords' => '',
'description' => '',
'login_needed' => FALSE
);
$config['menu']["bruidsmode"] = array (
'title' => '',
'url' => 'bruidsmode.php',
// 'mobile' => 'bruidsmode.php',
// 'mobile' => 'bruidsmode.php',
'keywords' => '',
'description' => '',
'login_needed' => TRUE,
'robot' => FALSE
);
if(isset($_POST['generalsearch']) && isset($_POST['generalsearchresult'])){
// Put search value into variable
$searchvalue = $_POST['generalsearchresult'];
// Fill variable with all page items
$array = $config['menu'];
// Set search cretaria to search in array
$key = $searchvalue;
// Search for key value inside array
$result = #$array[$key] ?: null;
if($result == null){
echo "Geen resultaten gevonden...";
}else{
var_dump($result);
}
}
?>
<form method="POST">
<input type="text" name="generalsearchresult">
<input type="submit" name="generalsearch">
</form>
The above code works but only outputs arrays which exactly match the search criteria. So for example the searchterm "bruidsmode" with the above code outputs only the page "bruidsmode" but not the page "bruidsmode-overzicht" for example.
I hope the above is understandable, if not please tell me how to improve it.
Kind regards,
Robbert
Your code isn't really what I would call a search. In order to search you should loop over the array to find potential matches, rather than return the requested property.
function searchMenu($menu, $term) {
$matches = [];
foreach($menu as $key => $value) {
if (stripos($key, $term) !== false) {
$matches[] = $value;
}
}
return $matches;
}
if(isset($_POST['generalsearch']) && isset($_POST['generalsearchresult'])){
$result = searchMenu($config['menu'], $_POST['generalsearchresult']);
if(!count($result)){
echo "Geen resultaten gevonden...";
}else{
var_dump($result);
}
}
If you want to return multiple results, you will need to store them in an array and return that.
If you are going to do that, you can extend the search to check against child fields as well, not just the top level keys:
$page_data =[
'my-cat' => [
'title' => '',
'url' => 'my-cat.php',
'mobile' => 'my-cat.php',
'keywords' => 'cat,kitten',
'description' => 'i love my cat',
'login_needed' => false,
'original_page' => 'mycat',
],
'home' => [
'title' => '',
'url' => 'home.php',
'mobile' => 'home.php',
'keywords' => 'cat,dog,other',
'description' => 'a site about cats',
'login_needed' => false,
'original_page' => 'home',
],
'about' => [
'title' => '',
'url' => 'about.php',
'mobile' => 'about.php',
'keywords' => 'about',
'description' => 'about me',
'login_needed' => false,
'original_page' => 'about',
],
];
function search(array $page_data_to_search, string $search_term, array $fields_to_search): array{
$out=[];
$search_fields = array_flip($fields_to_search); //O(1)
foreach($page_data_to_search as $key => $page_data){
//first test the key
if(isset($search_fields['key']) && strpos($key, $search_term) !==false){
$out[$key]=$page_data;
continue; //no need to check other fields
}
//then the user supplied fields
foreach($search_fields as $field => $unused){
if(isset($page_data[$field]) && strpos($page_data[$field], $search_term) !==false){
$out[$key]=$page_data;
break;
}
}
}
return $out;
}
echo '<pre>';
var_dump(search($page_data, 'cat', ['key', 'keywords', 'description']));

Filtering inputs

Alright, so I have written this function to filter inputs received from a form.
For example the correct input would be foobar, but people can misspell it as `fo'bar'. The ' should not be there.
I have written this simple function which does what is required. (Need to remove the ' from the inputs).
But what would be a more better way to perform this ?
My function :
function normalize_string($string)
{
$newString = "";
for($i=0;$i<strlen($string);$i++)
{
if($string[$i] != "'")
{
$newString = $newString . $string[$i];
}
}
return $newString;
}
Array
if (isset($_POST['submit'])){
$db->insert('customers', array(
'Businessname' => $_POST['BusinessnameTextbox'],
'Salutation' => $_POST['SalutationTextbox'],
'Firstname' => $_POST['FirstnameTextbox'],
'Middle' => $_POST['MiddleTextbox'],
'Lastname' => $_POST['LastnameTextbox'],
'Zipcode' => $_POST['ZipcodeTextbox'],
'Housenumber' => $_POST['HousenumberTextbox'],
'Street' => $_POST['StreetTextbox'],
'Place' => $_POST['PlaceTextbox'],
'Country' => $_POST['CountryTextbox'],
'Phone1' => $_POST['Phone1Textbox'],
'Phone2' => $_POST['Phone2Textbox'],
'Phone3' => $_POST['Phone3Textbox'],
'Phone4' => $_POST['Phone4Textbox']
));
}
You could always use regular expressions, as in
$lastname = preg_replace("/'/", "", $_POST['LastnameTextbox']);
Just curious, how would d'Artagnan register at your site?

Get previous and next values in array

I have array, for example:
<?php
$array = array(
0 => array(
'subject' => 'Stackoverflow',
'body' => '',
'name' => 'php'
),
1 => array(
'subject' => 'Test',
'body' => 'Wayne',
'name' => ''
),
2 => array(
'subject' => '',
'body' => 'this is ok',
'name' => ''
),
3 => array(
'subject' => 'cnn',
'body' => 'Google',
'name' => 'private'
),
4 => array(
'subject' => 'code',
'body' => '',
'name' => '7777'
)
);
And i would like get subject, body and name for key 2 and if key not exist then this should get from previous and next (separate function) values.
For example if i want get value from 2 key:
function getCurrentOrPrevious(2);
should return:
array(
'subject' => 'Test', //from [1]
'body' => 'this is ok', //from [2] - current and exist
'name' => 'php' //from [0] - in from [2] and [1] not exist
)
function getCurrentOrNext(2);
should return:
array(
'subject' => 'cnn', //from [3]
'body' => 'this is ok', //from [2] - current
'name' => 'php' //from [3]
)
How is the best way for this? Are there any functions in PHP for such operations?
LIVE
Assuming, you fill your array similar to $array[] = $value; [i.e. that you have consecutive numeric keys starting from zero]:
## $array is the array to take values from, $key is the target key
## $fields are required fields
function getCurrentOrPrevious($array, $key, $fields) {
if ($key < 0) return null;
$output = array();
foreach ($fields as $field) {
for ($i = $key; $i >= 0; $i--) {
if (!empty($array[$i][$field])) {
$output[$field] = $array[$i][$field];
break;
}
}
return $output;
}
Use as follows:
$my_values = getCurrentOrPrevious($array, 12, array('subject', 'body', 'name'));
I guess you could use empty() function of php to check. Also you should think about how far that function shell go?
What if [3] (next) also has an empty value at the same position
What if previous index is <0?
UPDATE
function getCurrOrNext($array, $index){
$keys = array_keys($array[$index]);
foreach($keys AS $key){
if($array[$index][$key] == "") {
$array[$index][$key] = (!empty($array[$index+1]) && !empty($array[$index+1][$key])?$array[$index+1][$key]:null);
}
}
return $array;
}
I guess something like this
function getCurrentOrPrev($array, $key) {
while(key($array)!==$key) next($array); //move internal pointer to required position first
$result = current($array);
//loop is going to execute as long as at least one of elements is empty and we didn't get to beginning of array yet
while((empty($result['subject'])
|| empty($result['body'])
|| empty($result['name']))
&& prev($array)!==false) {
$c = current($array);
//replace empty elements with values of current element
$result['subject'] = empty($result['subject']) ? $c['subject'] : '';
$result['body'] = empty($result['body']) ? $c['body'] : '';
$result['name'] = empty($result['name']) ? $c['name'] : '';
}
return $result;
}
For function with next simply replace prev() method with next(), or to minimize code duplication You may introduce third parameter and call correct method based on its value.
This method doesn't care about values of the key other but the key specified in parameter.
You may have mixed literal and numeric indexes.

Semi-advanced PHP array

So I'm new to Arrays, but I think this should be fairly easy, I just can't wrap my head around it.
I've got an array, that can have a varying amount of keys in it, based on how much input is given by the user.
$array = MY_Class( array(
'type' => 'representatives',
'show_this_many' => '10'
));
easy enough, right?
but I've got 1-4 more keys that could be in it, based on user input. They fill out a form on the first page, and it submits to the second page (which contains the array above).
I need to grab City, State, First, last, based on how many fields the user fills out on the previous page. I can't have blank ones so
$array = MY_Class( array(
'type' => 'representatives',
'show_this_many' => '10',
'city' => '',
'state' => '',
'first' => $_GET['first']
));
won't really work. I need a way to determine which fields have been submitted (preferrably via GET) and build the array that way. so can end up with
$array = MY_Class( array(
'type' => 'representatives',
'show_this_many' => '10',
'state' => $_GET['state'],
'first' => $_GET['first']
));
because state and first had a value while city and last did not.
The first thing that came to mind was something like
$array = MY_Class( array(
'type' => 'representatives',
'show_this_many' => '10',
$constants => $variables
));
//where
$constants = array( //_GET stuff values );
$variables = array( //_GET stuff with values );
// magic method to make it like
// CONSTANTS[0] => VARIABLES[0];
// CONSTANTS[1] => VARIABLES[1];
// so everything is lined up
but I'm not sure how to do it :/
You will want to use a whitelist of possible keys from $_GET so your array doesn't get polluted with spurious (or possibly malicious) keys, and then you can simply append them onto your array with a loop over $_GET.
// Your array is already initialized with some values:
$array = array(
'type' => 'representatives',
'show_this_many' => '10'
);
// Allowed GET keys
$allowed = array('city','state','first');
// Loop over get and add the keys (if allowed)
foreach ($_GET as $key => $value) {
// If the key is allowed and the value isn't blank...
if (in_array($allowed, $key) && !empty($value)) {
$array[$key] = $value;
}
}
// See all the newly added keys...
var_dump($array);
Another option is to just add all the keys to the array, then call array_filter() to remove the blanks.
$array = array(
'type' => 'representatives',
'show_this_many' => '10',
'city' => '',
'state' => '',
'first' => ''
);
// Add values from $_GET, then filter it
$array = array_filter($array, function($val) {
return $val !== '' && !is_null($val);
});
Try the below code
$array = array(
'type' => 'representatives',
'show_this_many' => '10'
);
$fields = array ('city', 'state', 'first');
foreach ($fields as $field) {
if (!empty($_GET[$field])) {
$array[$field] = $_GET[$field]
}
}

Cant seem to append to array in php

This simple script should theoretically check the form for errors and then print any errors it finds.
The formValidate function takes in a form array, each field in the form has a value which is validated. The field also has an errors key whose value is an empty array. I am trying to append any errors I find to the errors array of the particular field. I then return the form array when I am done.
I later print out all the errors for the fields. Unfortunately the errors never show up.
I have been breaking my head over this for many hours now and I cant for the life of me figure out why the form errors in my script are not appeding.
Any help would be greatly appreciated!
# get value from array
function array_get(array $array, $key, $default = null)
{
return (array_key_exists($key, $array)) ? $array[$key] : $default;
}
# get string value from array
function array_get_string(array $array, $key, $default = '', $trim = true)
{
$val = array_get($array, $key);
if (is_string($val)) {
return ($trim) ? trim($val) : $val;
}
return $default;
}
function validateForm($form)
{
// validateField each field
foreach ($form as $field)
{
foreach ($field['validation'] as $validate)
{
switch($validate)
{
case 'email':
if(!filter_var($field['value'], FILTER_VALIDATE_EMAIL)) {
$field['errors'][] = $field['value'] . ' is an invalid email address.';
}
break;
case 'number':
if(!preg_match('/^[0-9 ]+$/', $field['value'])) {
$field['errors'][] = $field['value'] . ' is an invalid number.';
}
break;
case 'alpha':
if(!preg_match('/^[a-zA-Z ]+$/', $field['value'])) {
$field['errors'][] = $field['value'] . ' contains invalid characters. This field only accepts letters and spaces.';
}
break;
}
}
}
return $form;
}
// $post = filter_input_array( INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS );
$post = $_POST;
$ajax = array_get_string($post, "request_method") == 'ajax';
# select data that needs validation
$form = array(
'fullname' => array(
'value' => array_get_string($post, "full-name"),
'validation' => array('alpha', 'required'),
'errors' => array(),
),
'emailaddress' => array(
'value' => array_get_string($post, "email-address"),
'validation' => array('email'),
'errors' => array(),
),
'activites' => array(
'value' => array_get_string($post, "activites"),
'validation' => array('default'),
'errors' => array(),
),
'country' => array(
'value' => array_get_string($post, "country"),
'validation' => array('default'),
'errors' => array(),
),
'contactpreference' => array(
'value' => array_get_string($post, "contact-preference"),
'validation' => array('default'),
'errors' => array(),
),
'message' => array(
'value' => array_get_string($post, "message"),
'validation' => array('alpha'),
'errors' => array(),
),
);
// validate the form
$form = validateForm($form);
foreach ($form as $field)
{
foreach ($field['errors'] as $error)
{
echo $error . '<br />';
}
}
foreach creates a copy of the array and works on it. If you need to make changes to the original array, pass it by reference like so:
foreach($form as &$field) {
...
}

Categories