How to identify a PHP variable is an array or not - php

How to check whether the PHP variable is an array?
$value is my PHP variable and how to check whether it is an array?

echo is_array($variable);
http://us3.php.net/is_array

php has function named is_array($var) which returns bool to indicate whether parameter is array or not
http://ir.php.net/is_array

is_array — Finds whether a variable is an array
http://uk.php.net/is_array

I'm adding a late answer here as I think I've got a better solution if people are using multiple array checks.
If you're simply checking a single array, then using PHP's is_array() does the job just fine.
if (is_array($users)) {
is an array
} else {
is not an array
}
However, if you're checking multiple arrays - in a loop for example - then there is a much better performing solution for this, using a cast:
if ( (array) $users !== $users ) {
// is not an array
} else {
// is an array
}
THE PROOF
If you run this performance test, you will see quite a performance difference:
<?php
$count = 1000000;
$test = array('im', 'an', 'array');
$test2 = 'im not an array';
$test3 = (object) array('im' => 'not', 'going' => 'to be', 'an' => 'array');
$test4 = 42;
// Set this now so the first for loop doesn't do the extra work.
$i = $start_time = $end_time = 0;
$start_time = microtime(true);
for ($i = 0; $i < $count; $i++) {
if (!is_array($test) || is_array($test2) || is_array($test3) || is_array($test4)) {
echo 'error';
break;
}
}
$end_time = microtime(true);
echo 'is_array : '.($end_time - $start_time)."\n";
$start_time = microtime(true);
for ($i = 0; $i < $count; $i++) {
if (!(array) $test === $test || (array) $test2 === $test2 || (array) $test3 === $test3 || (array) $test4 === $test4) {
echo 'error';
break;
}
}
$end_time = microtime(true);
echo 'cast, === : '.($end_time - $start_time)."\n";
echo "\nTested $count iterations."
?>
THE RESULT
is_array : 7.9920151233673
cast, === : 1.8978719711304

Related

PHP: Check whether array_filter deleted any entry from the array

is there any way to check whether array_filter deleted any value from an array?
The solutions I've thought of are these ones:
$sample_array = ["values"];
$array_copy = $sample_array;
if (array_filter($sample_array, 'fn') === $array_copy) {
#Some value was deleted from the array
} else {
#The array was not modified
}
This one doesn't seem very efficient, as it has to copy the entire array.
$sample_array = ["values"];
$array_count = count($sample_array);
if (count(array_filter($sample_array, 'fn')) === $array_count) {
#The array was not modified
} else {
#Some value was deleted from the array
}
This one seems more efficient, though I was wondering if there was a more elegant way of approaching the issue.
Thank you beforehand.
You can extend your function to keep track of the change itself.
$array = [1, 2, 3, 4];
$changed = 0;
$new = array_filter($array, function($e) use (&$changed) {
$result = $e <= 2;
if(!$result) $changed++;
return $result;
});
Returns $changed as 2.
Use array_diff to compare two arrays.
if(array_diff($array_copy, $sample_array))
echo "not same";
Using 'count()' is IMHO the most elegant solution and, I suspect, may be a lot more efficient - you'd need to measure it. OTOH, for your consideration...
function fn($arg, $mode='default')
{
static $matched;
if ('default'==$mode) {
$result=real_filter_fn($arg);
$matched+=$result ? 1 : 0;
return $result;
}
$result=$matched;
$matched=0;
return $result;
}
If you want to keep track of the removed elements, you could do something like this.
$sample_array = ['values', 'test'];
$removed = []; // Contains all the removed values.
$new_array = array_filter($sample_array, function($value) use (&$removed) {
if($value == 'test') {
$removed[] = $value; // Adds the value to the removed array.
return false;
}
return true;
});
print_r($removed);
You could use a closure to change the state of a boolean variable:
$sample_array = [1,2,3,4];
$array_changed = false;
//Use closure to change $array_changed
print_r(array_filter($sample_array, function($var) use (&$array_changed) {
$check = (!($var & 1));
$array_changed = $array_changed?:$check;
return $check;
}));
if ($array_changed) {
#Some value was deleted from the array
} else {
#The array was not modified
}
[EDIT]
This is a simple speedtest of your solutions compared to mine:
/**********************SPEEDTEST**************************/
function fn ($var) {
return (!($var & 1));
}
$sample_array = [1,2,3,4];
$before = microtime(true);
for ($i=0 ; $i<100000 ; $i++) {
$array_changed = false;
//Use closure to change $array_changed
array_filter($sample_array, function($var) use (&$array_changed) {
$check = (!($var & 1));
$array_changed = $array_changed?:$check;
return $check;
});
if ($array_changed) {
#Some value was deleted from the array
} else {
#The array was not modified
}
}
$after = microtime(true);
echo "Using closure:      " . ($after-$before)/$i . " sec/run\n";
echo '<br>';
/*******************************************************/
$before = microtime(true);
for ($i=0 ; $i<100000 ; $i++) {
$array_copy = $sample_array;
if (array_filter($sample_array, 'fn') === $array_copy) {
#Some value was deleted from the array
} else {
#The array was not modified
}
}
$after = microtime(true);
echo "Using array copy:    " . ($after-$before)/$i . " sec/run\n";
echo '<br>';
/*******************************************************/
$before = microtime(true);
for ($i=0 ; $i<100000 ; $i++) {
$array_count = count($sample_array);
if (count(array_filter($sample_array, 'fn')) === $array_count) {
#The array was not modified
} else {
#Some value was deleted from the array
}
}
$after = microtime(true);
echo "Using array count:   " . ($after-$before)/$i . " sec/run\n";
The results:
Using closure: 9.1402053833008E-7 sec/run
Using array copy: 4.9885988235474E-7 sec/run
Using array count: 5.5881977081299E-7 sec/run
Maybe that helps with decision-making :)

Generate IF conditions from function

I have an if statement that is used in two different functions against the same conditions. The problem is that the conditions end up fairly long (5-7 ORs) and may need to be modified in the future. If they end up being modified, the conditions will change the same way in both functions.
Example of one if statement:
if ($this->object === 'one' || $this->object === 'two' || $this->object === 'three' ) {
echo 'Yes!';
} else {
echo 'No!';
};
I am thinking of creating an array and a function that will feed into the if statement but can't think of any way to get the if statement to check the condition rather than checking the presence of input.
$this->object = 'one';
$test_array = array('one', 'two', 'three');
function stmbuilder($array) {
$count = count($array);
$stm = '';
for ($i = 0; $i < $count; $i++) {
$intro = '$this->object ===';
$connector = ($i < $count-1 ? ' || ' : '');
$stm .= $intro . $array[$i] . $connector;
}
return $stm;
}
$condition = stmbuilder($test_array);
if ($condition) {
echo 'Yes!';
} else {
echo 'No!';
} //Will always echo Yes! since $condition has a value but does not check against what $this->object is
Any help is appreciated!
Why not just in_array()?
$arr = array('one', 'two', 'three');
in_array('four', $arr) -> false
in_array('two', $arr) -> true

Checking a for progression in a list of variables

Let's say I want to check for simple mathematical progression. I understand I can do it like this:
if ($a<$b and $b<$c and $c<$d and $d<$e and $e<$f) { echo OK; }
Is there a way to do it in a more convenient way? Like so
if ($a..$f isprog(<)) { echo OK; }
I don 't know if I get your problem right. But propably the solution for your progression could be the SplHeap object of the SPL delivered with php.
$stack = new SplMaxHeap();
$stack->insert(1);
$stack->insert(3);
$stack->insert(2);
$stack->insert(4);
$stack->insert(5);
foreach ($stack as $value) {
echo $value . "\n";
}
// output will be: 5, 4, 3, 2, 1
I havent heard of something like this, but how about using simple function:
function checkProgress($vars){ //to make it easie i assume that vars can be given in an array
$result = true;
for ($i=0; $i<= count($vars); $i++){
if ($i>0 && $vars[$i] > $vars[$i-1]) continue;
$result = false;
}
return $result;
}
Solved it quick and dirty:
function ispositiveprogression($vars) {
$num=count($vars)-1;
while ($num) {
$result = true;
if ($vars[$num] > $vars[$num-1]) {
$num--;
}
else { $result = false; break; }
}
return $result;
}
Create an array of values, iterate over them and maintaining a flag that checks if the current element value is greater than / less than that of the next value. Unlike some of the solutions in this thread, this doesn't loop through the whole array. It stops looping when it discovers the first value that's not a progression. This will be a lot more faster if the operation involves a lot of numbers.
function checkIfProg($arr, $compare) {
$flag = true;
for ($i = 0, $c = count($arr); $i < $c; $i++) {
if ($compare == '<') {
if (isset($arr[$i + 1]) && $arr[$i] > $arr[$i + 1]) {
$flag = false;
break;
}
} elseif ($compare == '>') {
if (isset($arr[$i + 1]) && $arr[$i] < $arr[$i + 1]) {
$flag = false;
break;
}
}
}
return $flag;
}
Usage:
$a = 2;
$b = 3;
$c = 4;
$d = 5;
$e = 9;
$f = 22;
$arr = array($a, $b, $c, $d, $e, $f);
var_dump(checkIfProg($arr, '<')); // => bool(true)
If you want the array to be created dynamically, you could use some variable variable magic to achieve this:
$arr = array();
foreach (range('a','f') as $v) {
$arr[] = $$v;
}
This will create an array containing all the values of variables from $a ... $f.

php check array index out of bounds

Consider the following array.
$a['a'] = 1;
$a['b'] = 2;
$a['c'] = 3;
$a['d'] = 4;
and then i am looping the array
foreach( $a as $q => $x )
{
# Some operations ....
if( isLastElement == false ){
#Want to do some more operation
}
}
How can i know that the current position is last or not ?
Thanks.
Take a key of last element & compare.
$last_key = end(array_keys($a));
foreach( $a as $q => $x )
{
# Some operations ....
if( $q == $last_key){
#Your last element
}
}
foreach (array_slice($a, 0, -1) as $q => $x) {
}
extraProcessing(array_slice($a, -1));
EDIT:
I guess the first array_slice is not necessary if you want to do the same processing on the last element. Actually neither is the last.
foreach ($a as $q => $x) {
}
extraProcessing($q, $x);
The last elements are still available after the loop.
You can use the end() function for this operation.
<?php
$a['a'] = 1;
$a['b'] = 2;
$a['c'] = 3;
$a['d'] = 4;
$endkey= end(array_keys($a));
foreach( $a as $q => $x )
{
# Some operations ....
if( $endkey == $q ){
#Want to do some more operation
echo 'last key = '.$q.' and value ='.$x;
}
}
?>

Check how many variables equal zero with php

I have numerous variables and I need to print a numeric value for how many of these variables are equal to zero:
$var1 = '2';
$var2 = '0';
$var3 = '4';
//check how many variables = 0
$zeros = ?
//should be a numeric value this example should print '1'
echo $zeros
Thanks for any suggestions!
This gets a list of all defined variables, and counts how many are === 0 and excludes the $_GET, $_POST, and $_COOKIE globals.
If you define this code in a function, then only the variables in that scope are counted.
<?php
$value = 0;
$var = 1;
$test = false;
$nine = 0;
$zero = 9;
$zeroes = 1; // set to 1 so we don't count this
$vars = get_defined_vars();
foreach($vars as $var) {
if (is_array($var) && (
isset($var['_GET']) || isset($var['_POST']) ||
isset($var['_COOKIE']))
) {
continue; // don't count superglobal arrays
}
if ($var === 0) $zeroes++;
}
$zeroes -= 1; // subtract the initial value
echo "There are $zeroes zero values."; // There are 2 zero values.
EDIT: It could be modified to be a function that would work recursively if you needed to check the values of arrays for example. You could call it from the global scope like this:
$zeroes = countZero(get_defined_vars());
And then the function could detect arrays and call itself until it has searched all vars.
if($var1 == 0) $zeros++; repeat for var2, 3, etc.
Use variable variables to generate variables from a string if they all follow the varX pattern where X is a number.
$var1 = '2';
$var2 = '0';
$var3 = '4';
$zeros = 0;
for($i = 1; $i <= 3; $i++) {
$var = ${'var' . $i};
if($var == 0) $zeros ++;
}
echo $zeros;
I do not understand the purpose of what you are trying to achieve here and maybe I am misunderstanding the need but the following yet simple code does it:
$var1 = '2';
$var2 = '0';
$var3 = '4';
$zeros = ($var1 =='0')?1:0 + ($var2 =='0')?1:0 + ($var3 =='0')?1:0;
echo $zeros
Basically I nested ternaly conditional expressions instead of using regular if then elses.
I put all of my variables into an array, looped with foreach and added to the $zeros variable:
$values = array('0' => $var1, '1' => $var2, '2' => $var3);
$zeros = 0;
foreach($values as $v) {
if($v === '0')
$zeros++;
}
echo $zeros;
I found this was an easy solution, thanks for the input though!

Categories