Evaluate a dynamic array key - php

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

Related

How to test if array has empty value in it?

I have an array that I want to test for empty elements, I have tried using array_walk to walk an array (a single dimension array) and return true if the array of elements (values) has got any empty elements.
I naturally went to the PHP website, looked at the examples on offer and they don't make any sense because it does not give a clear example of how you would use array_walk for this. I tried array_filter and that didn't seem to do much either.
Example of what I was trying to do.
$test = array("Tree"=>"Ash","TreeID"=>"Q23-123","count"=>14,"User"=>"P.Williams");
$result = array_walk( $test, "empty", true );
All I get as a result is "Array".
and PHP parser is having a hissy fit about it, they say clearly, bool array_walk ( array &$array , callable $callback [, mixed $userdata = NULL ] ) in their site, this I deduced to be something $result array_walk ( $theTargetArray, "StringNameOfFunction", theResultIfTure); but nothing is that simple.
So far I have found lots of examples on many sites and it seems that people have just copied and pasted the PHP examples, some have changed their names to hide that they have copied and pasted the example...
Can someone let me know what it is that I am doing wrong here please?
(Also FAO stackoverflow site maintainers, What is the point in suggesting a tag, I click to use it and then I get told I can not create a new tag unless I have 1500 points??? Seriously Why? Good idea if you go and think about that one.)
$my_arr = array(....); // your array here
$has_empty_value = sizeof($my_arr) != sizeof(array_filter($my_arr));
array_walk is not going to help you on that. It's a mutator function, and is intended to change array elements, not to retrieve information about them. What you're looking for is a boolean aggregator function known as any or some in other languages. PHP doesn't provide it out of the box, so you have to write it by hand:
function any($iter, $pred) {
foreach($iter as $item)
if($pred($item))
return true;
return false;
}
However, an attempt to use it with empty, as in
print any($test, 'empty')
will fail, because empty is not a real function and can't be used indirectly. A workaround is to wrap it in yet another function and pass that one to any:
any($test, function($x) { return empty($x); })
Another option is to filter an array through boolval, thus removing "falsy" values, and compare lengths:
$hasEmptyElements = count(array_filter($test, 'boolval')) < count($test);
Note that, unlike any, which is "lazy", filter always processes the whole array.
The docs for array_walk say "Applies the user-defined callback function to each element of the array array." Therefore, you can use it with your own callbacks or with with a closure, like so:
$test = array("Tree"=>"Ash","TreeID"=>"Q23-123", "count"=> 14, "User"=>"P.Williams");
$result = array_walk( $test, function($value) {
return empty($value);
});
Of course, this depends on what you are trying to achieve as this will loop through all the values and $result will be true if all the values are empty but the last one is not.
If you are looking to find out if any of the values are empty, a function that stops after it finds an empty item would be better:
function hasEmptyValues(array $array)
{
foreach ($array as $key => $value) {
if (empty($value)) {
//Empty value found
return true;
}
}
//None of the values are empty
return false;
}

PHP: If condition with explode within foreach loop

I am trying to get multiple value from user input from text field and want to explode or keep adding into if condition statement
Here is my code
foreach ($list['post'] as $item) {
if( ($item['single']['catid'] != 8) AND ($item['single']['catid'] != 4) ){
$this->list_post($item);
}
}
Now what exactly I am looking for is in if( ($item['single']['catid'] != 8) AND ($item['single']['catid'] != 4) ) I want allow user to add multiple category ID and each ID will add AND and further id code AND ($item['single']['catid'] != 4)
I never done this before and don't know either this is proper way to do or any other possible better way.
Thanks a lot
You should have some kind of an array of the category IDs you want to check for, for example:
$categories = array(8, 4);
Then you could use something like the in_array(needle, haystack) built-in function of PHP.
Your if condition would become like that one: if (!in_array($item['single']['catid'], $categories)) {.
You should be using the above, but I am going to give you an idea of how it works, so you can understand the principle for more complex issues:
function exists($target, $array) {
foreach ($array as $element) { // Go through each element in the array
if ($element == $target) { // Check to see if any element there is what you are searching for
return true; // Return true, that it does exist, and stop there.
} else {
// Just ignore it...
}
}
return false; // If you get here, it means nothing returned true, so it does not exist...
}
To be used as if (exists($item['single']['catid'], $categories)) {.
It wouldn't work if it was "inside" the if statement because you have to do some processing before evaluating if it exists or not. So you either could have done that before the if statement, and store the result in a variable, or use a function (which PHP provides).
Hopefully the concept will help you fir more complex problems...
Note: this assumes your input is in the form of an array, which you can build via various ways, if not provided as is directly.
Update:
The input you get via the input field is sent through form, to which you specify either POST or GET as a method. Assuming it is POST that you are using, this is how you'd get the input as a string as it was entered in the text field:
$categories_string = $_POST['the_name_field_in_the_input_tag'];
After that you have to understand it as a list of items, let's say separated by commas: 1,3,5,8. Then this is simply separating by commas. You can use explode($delimiter, $string). Like that:
$categories_array = explode(',', $_POST['categories']);
But you cannot trust the input, so you could get something like 1, 2, 3,5,6. The spaces will mess it up, because you will have spaces all around. To remove them you can use trim for example.
$categories = array(); // Create the array in which the processed input will go
foreach ($categories_array as $c) { // Go through the unprocessed one
$categories[] = trim($c) * 1; // Process it, and fill the result. The times one is just so that you get numbers in the end and not strings...
}
Then you can use it as shown earlier, but keep in mind that this is just an example, and you might not even need all these steps, and there are much more efficient ways to process this input (regular expressions for example). But the concern here is not sanitizing input, but keep in mind you will need to do that eventually.
Hope it's clear enough :)
You might be better off with in_array() for checking a value against a variable number of possibilities.
I'm not sure I understand your problem. You want user to be able to input different values, e.g.:
$string = "5, 6, 7, 8, 10";
Afterwards, you want to check if 'catid' is not in that array and if it isn't you want to run $this->list_post($item);
If so, then you should use something like this:
$values = explode(", ", $string); //make array from values
foreach ($list['post'] as $item) {
if (!in_array($item['single']['catid'], $values)) { //check whether catid is in array
$this->list_post($item); // execute whatever you want
}
}
Hope it helps.

PHP isset not working properly on form, with loops and arrays

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.

Check if a option in a form that was selected is the same as a variable in an array

I'm trying to validate some form data before adding it to a database however I need to validate that the option was an option that is in the form, not just one that was added with something like Firebug.
I tried using if and comparing the posted values like this: (there is another 27 options, and 3 more option fields)
if($data['selection'] == 'some_option' || $data['selection'] == 'some_option2') {
However it makes extremely long lines of code and its difficult to manage. So I thought about making an array that stores the possible options, then when its submitted, check if the selected option matches one of the entries in the array.
One of my ideas was to do a loop and check if it's equal:
for($i = 1; $i < sizeof($options[$currentselection]); ++$i) {
if($option[$i] == $data[$currentselection]) {
return true;
} else {
return false;
}
}
However I'd have to do one of these for each of the selection fields (which I'd rather not do). So is there a way of cleaning it up and having it all in one? Also, I'm using codeigniter.
A simple way is to use the in_array function
$values=Array('op1','op2',...);
return in_array($data['selection'],$values);
Or you can do this:
$values=Array(
'selection'=>Array('op1','op2'),
'another_field'=>Array('op3','op4'),
);
return in_array($data[$field],$values[$field]);

PHP: testing for existence of a cell in a multidimensional array

I have an array with numerous dimensions, and I want to test for the existence of a cell.
The below cascaded approach, will be for sure a safe way to do it:
if (array_key_exists($arr, 'dim1Key'))
if (array_key_exists($arr['dim1Key'], 'dim2Key'))
if (array_key_exists($arr['dim1Key']['dim2Key'], 'dim3Key'))
echo "cell exists";
But is there a simpler way?
I'll go into more details about this:
Can I perform this check in one single statement?
Do I have to use array_key_exist or can I use something like isset? When do I use each and why?
isset() is the cannonical method of testing, even for multidimensional arrays. Unless you need to know exactly which dimension is missing, then something like
isset($arr[1][2][3])
is perfectly acceptable, even if the [1] and [2] elements aren't there (3 can't exist unless 1 and 2 are there).
However, if you have
$arr['a'] = null;
then
isset($arr['a']); // false
array_key_exists('a', $arr); // true
comment followup:
Maybe this analogy will help. Think of a PHP variable (an actual variable, an array element, etc...) as a cardboard box:
isset() looks inside the box and figures out if the box's contents can be typecast to something that's "not null". It doesn't care if the box exists or not - it only cares about the box's contents. If the box doesn't exist, then it obviously can't contain anything.
array_key_exists() checks if the box itself exists or not. The contents of the box are irrelevant, it's checking for traces of cardboard.
I was having the same problem, except i needed it for some Drupal stuff. I also needed to check if objects contained items as well as arrays. Here's the code I made, its a recursive search that looks to see if objects contain the value as well as arrays. Thought someone might find it useful.
function recursiveIsset($variable, $checkArray, $i=0) {
$new_var = null;
if(is_array($variable) && array_key_exists($checkArray[$i], $variable))
$new_var = $variable[$checkArray[$i]];
else if(is_object($variable) && array_key_exists($checkArray[$i], $variable))
$new_var = $variable->$checkArray[$i];
if(!isset($new_var))
return false;
else if(count($checkArray) > $i + 1)
return recursiveIsset($new_var, $checkArray, $i+1);
else
return $new_var;
}
Use: For instance
recursiveIsset($variables, array('content', 'body', '#object', 'body', 'und'))
In my case in drupal this ment for me that the following variable existed
$variables['content']['body']['#object']->body['und']
due note that just because '#object' is called object does not mean that it is. My recursive search also would return true if this location existed
$variables->content->body['#object']->body['und']
For a fast one liner you can use has method from this array library:
Arr::has('dim1Key.dim2Key.dim3Key')
Big benefit is that you can use dot notation to specify array keys which makes things simpler and more elegant.
Also, this method will work as expected for null value because it internally uses array_key_exists.
If you want to check $arr['dim1Key']['dim2Key']['dim3Key'], to be safe you need to check if all arrays exist before dim3Key. Then you can use array_key_exists.
So yes, there is a simpler way using one single if statement like the following:
if (isset($arr['dim1Key']['dim2Key']) &&
array_key_exists('dim3Key', $arr['dim1Key']['dim2Key'])) ...
I prefer creating a helper function like the following:
function my_isset_multi( $arr,$keys ){
foreach( $keys as $key ){
if( !isset( $arr[$key] ) ){
return false;
}
$arr = $arr[$key];
}
return $arr;
}
Then in my code, I first check the array using the function above, and if it doesn't return false, it will return the array itself.
Imagine you have this kind of array:
$arr = array( 'sample-1' => 'value-1','sample-2' => 'value-2','sample-3' => 'value-3' );
You can write something like this:
$arr = my_isset_multi( $arr,array( 'sample-1','sample-2','sample-3' ) );
if( $arr ){
//You can use the variable $arr without problems
}
The function my_isset_multi will check for every level of the array, and if a key is not set, it will return false.

Categories