Check whether certain array keys are given or not - php

I'm writing some kind of a function that accepts an associative array as an argument.
This array can be:
Empty
Has only one element. With key either pageParam or wrapperClass.
Has two elements. Must be keyed with pageParam and wrapperClass.
Now i've written these checks to ensure that:
The array is not more than 2 elements.
The array does not have any elements other than pageParam and wrapperClass
The problem is, My second check is not working properly. Here's my code :
public function init_paginator(array $parameters = array())
{
if(!empty($parameters))
{
// This check works
if(count($parameters) > 2)
{
throw new \Exception("Paginator only accepts 2 elements in array: pageParam and wrapperClass.");
}
// This check does not work, even if its condition is satisfied
if(!in_array(array_keys($parameters), array('pageParam', 'wrapperClass')))
{
throw new \Exception("Paginator only accepts 2 elements in array: pageParam and wrapperClass.");
}
// Code..
}
}
The exception in the second check is always thrown if i entered the array argument like :
array("dummyKey"=>"dummyValue")
array("dummyKey1"=>"dummyValue1", "dummyKey2"=>"dummyValue2")
array("pageParam"=>"test") Or array("wrapperClass"=>"wrapper_class")
array("pageParam"=>"test", "wrapperClass"=>"wrapper_class")
The last two inputs is what puzzles me! Why the exception is thrown despite that my arguments are right.

Your second check looks for the value array_keys($parameters) inside array('pageParam', 'wrapperClass'). It compares an array of strings with two string values.
What you want is the keys of $parameters to be equal to the values of array('pageParam', 'wrapperClass'), thus:
array_keys($parameters) === array('pageParam', 'wrapperClass');
For arrays, the === operator evaluates to TRUE if both arrays have the same key/value pairs in the same order and of the same types. If you don't care about order, you can use ==.
By the way, this check renders the first one useless.

The doc aren't as descriptive as they should be, but the intent with the two arrays as args is that the needle is an array and the haystack is an array of arrays (multi-dimensional) that may contain the needle array. I'm headed out so will look again later, but maybe this as an alternative:
if(count(array_diff_key(array_keys(array('pageParam', 'wrapperClass')), $parameters)) > 1) {
//exception
}

The problem is in the way you use in_array
It'll never work because it keeps matching an array array_keys($parameters) to strings within another array array('pageParam', 'wrapperClass')
So, it keeps returning false
See PHP: in_array
Using array( array('pageParam', 'wrapperClass'), array('pageParam'), array('wrapperClass'), array()) as second parameter for in_array might work.

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;
}

isset() returns true from a string variable accessed as an array with any key

I face a problem like this:
$area="Dhaka";
isset($area); //returns true which is OK
isset($area['division']); //returns true why?
// actually, any array key of area returns true
isset($area['ANY_KEY']);//this is my question 1
isset($area['division']['zilla');//now it returns false.
//as I know it should returns false but why previous one was true.
Now if I do this:
$area['division'] = "Dhaka";
isset($area); // returns true which is OK
isset($area['division']); // returns true it's also OK
isset($area['ANY_KEY']); // returns false. I also expect this
isset($area['division']['ANY_KEY']); // returns true why? question #2
Basically both of my questions are the same.
Can anyone explain this?
As with every programming language in existence, a string is stored as an array of characters.
If I did:
$area = "Dhaka";
echo $area[0];
It would return D.
I could also echo the whole string by doing:
echo $area[0].$area[1].$area[2].$area[3].$area[4];
PHP will also type juggle a string into 0 when passed in a manner that accepts only integers.
So by doing:
echo $area['division'];
You would essentially be doing:
echo $area[0];
and again, getting D.
That's why isset($area['division']) returns a true value.
Why doesn't $area['foo']['bar'] (aka $area[0][0]) work? Because $area is only a single-dimension array.
The best approach to handle this problem when you're working with a variable that could either be a string or an array is to test with is_array() before trying to treat your variable as an array:
is_array($area) && isset($area['division'])
PHP lets you treat a string as an array:
$foo = 'bar';
echo $foo[1]; // outputs 'a'
So
$area['division']
will be parsed/executed as
$area[0];
(the keys cannot be strings, since it's not REALLY an array, so PHP type-converts your division string by its convert-to-int rules, and gives 0), and evaluate to the letter D in Dhaka, which is obviously set.
Okay, here's a solution rather than explaining why isset isn't going to work properly.
You want to check if an array element is set based on it's index string. Here's how I might do it:
function isset_by_strkey($KeyStr,$Ar)
{
if(array_key_exists($KeyStr,$Ar))
{
if(strlen($Ar[$KeyStr]) > 0 || is_numeric($Ar[$KeyStr] !== FALSE)
{
return TRUE;
}
return FALSE;
}
}
isset_by_strkey('ANY_KEY',$area); // will return false if ANY_KEY is not set in $area array and true if it is.
The best way to access a linear array in php is
// string treated as an linear array
$string= "roni" ;
echo $string{0} . $string{1} . $string{2} . $string{3};
// output = roni
It is expected behaviour.
PHP Documentation covers this
You can try empty() instead.
If it is returning true for keys that do not exist there's nothing you can do; however, you can make sure that it doesn't have a negative effect on your code. Just use array_key_exists() and then perform isset() on the array element.
Edit: In fact, using array_key_exists() you shouldn't even need isset if it is misbehaving just use something like strlen() or check the value type if array_key_exists returns true.
The point is, rather than just saying isset($Ar['something']) do:
if(array_key_exists('something',$Ar) )
and if necessary check the value length or type. If you need to check the array exists before that of course use isset() or is_array() on just the array itself.

Checking for a string in array and add

How can i check if a string is already present withing an array before adding to it in php?
say if array is $value
$value[0]="hi";
$value[1]="hello";
$value[2]="wat";
I want to check if value exists in it before adding it to it.
$s='hi';
if (!in_array($s, $value)) {
$value[]=$s;
}
in_array() checks if that value (1st parameter) is in the array (2nd parameter), returns boolean (! negates it)
$value[]=$s will add the value to the array with the next index
There is another tricky way if you want to add a bunch of values into an array, but only if they are not there yet. You just have to organize these new values into another array and use a combination of array_merge() and array_diff():
//your original array:
$values=array('hello', 'xy', 'fos', 'hi');
//the values you want to add if they are not in the array yet:
$values_to_add=array('hi', 'hello', 'retek');
$values=array_merge($values, array_diff($values_to_add, $values));
//$values becomes: hello, xy, fos, hi, retek
You can use in_array($searchstring, $array)
in_array("hello", $value) returns true
in_array("hllo", $value) returns false
http://php.net/manual/en/function.in-array.php
http://php.net/manual/en/function.in-array.php
if(in_array("hello", $value)) { // needle in haystack
return TRUE;
}
in_array - Checks if a value exists in an array.
In case of in_array($searchstring, $array), remember, the comparison is done in a case-sensitive manner, if the $searchstring is a "String"
Example :
- in_array("wat", $value) returns true
- in_array("what", $value) returns false.
// Observe carefully
- in_array("WAT", $value) returns false.
if you're going to create a Set, it's much better to use array keys instead of values. Simply use
$values["whatever"] = 1;
to add a value, no need to check anything.

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.

How to check if a PHP array has any value set?

I am working on a signup form, I am using PHP and on my processing part I run some code, if a submitted item fails I then add it to an errors array.
Below is a snip of the code, I am at the point where I need to find the best method to determine if I should trigger an error.
So if there is a value set in the error array then I need to redirect and do some other stuff.
I was thinking of using isset or else is_array but I don't think that is the answer since I set the array using **$signup_errors = array()** wouldn't this make the is_array be true?
Can anyone suggest a good way to do this?
//at the beginning I set the error array
$signup_errors = array();
// I then add items to the error array as needed like this...
$signup_errors['captcha'] = 'Please Enter the Correct Security Code';
if ($signup_errors) {
// there was an error
} else {
// there wasn't
}
How does it work? When converting to boolean, an empty array converts to false. Every other array converts to true. From the PHP manual:
Converting to boolean
To explicitly convert a value to
boolean, use the (bool) or (boolean)
casts. However, in most cases the cast
is unncecessary, since a value will be
automatically converted if an
operator, function or control
structure requires a boolean argument.
See also Type Juggling.
When converting to boolean, the
following values are considered FALSE:
the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the string "0"
an array with zero elements
an object with zero member variables (PHP 4 only)
the special type NULL (including unset variables)
SimpleXML objects created from empty tags
Every other value is considered TRUE (including any resource).
You could also use empty() as it has similar semantics.
Perhaps empty()?
From Docs:
Return Values
Returns FALSE if var has a non-empty
and non-zero value.
The following things are considered to
be empty:
"" (an empty string)
0 (0 as an integer)
"0" (0 as a string)
NULL
FALSE
array() (an empty array)
var $var; (a variable declared, but without a value in a class)
Check if...
if(count($array) > 0) { ... }
...if it is, then at least one key-value pair is set.
Alternatively, check if the array is not empty():
if(!empty($array)) { ... }
Use array_filter if you already have keys, but want to check for non-boolean evaluated values.
<?php
$errors = ['foo' => '', 'bar' => null];
var_dump(array_filter($errors));
$errors = ['foo' => 'Oops', 'bar' => null];
var_dump(array_filter($errors));
Output:
array(0) {
}
array(1) {
["foo"]=>
string(4) "Oops"
}
Use:
<?php
if(array_filter($errors)) {
// Has errors
}
You could check on both the minimum and maximum values of the array, in this case you can have a large array filled with keys and empty values and you don't have to iterate through every key-value pair
if(!min($array) && !max($array)) { ... }
The language construct isset(), is for testing to see if variables and array elements are set and not NULL. Using is_array() would tell you if the argument you supply to it is an array. Thus, I do not think using isset() or is_array() would give you the correct and desired result that you are seeking.
The code:
$signup_errors = array();
means that ...
is_array($signup_errors);
would return true. However, this does not mean that the Boolean language rules of PHP would evaluate....
if($signup_errors)
{
//*Do something if $signup_errors evaluates to true*;
}
as true, unless some elements are added to it. When you did this,
$signup_errors['captcha'] = 'Please Enter the Correct Security Code';
you fulfilled the PHP language requirement for the array above to evaluate to true.
Now, if for some reason you wanted, or needed, to use isset() on the array elements in the future, you could. But, the conditional statement above is enough for you this case.
I should add an obvious answer here. If you initialise your error array as an empty array. And later want to check if it is no longer an empty array:
<?php
$errors = [];
if($errors !== [])
{
// We have errors.
}

Categories