什么是检查多个变量ALL在IF语句中是否等于相同值的简写方法? (PHP)

Is there a shorthand way of writing the code below?

if (($tstat=='no_prices')&&($l1stat=='no_prices')&&($l2stat=='no_prices')&&($l3stat=='no_prices'))
{                                   
    //do something
}

I tried using the below code,but it did something when one of the variables was not equal to 'no_prices'.

if (($tstat && $l1stat && $l2stat && $l3stat)=='no_prices')
{
    //do something
}

To check that the strings weren't causing problems I tried substituting 0 for 'no_prices' and 1 for other values, but the result was the same.

array_flip is several times faster than array_unique:

function all_equal($arr, $value) {
  return array_keys(array_flip($arr)) == array($value);
}

$arr = array($tstat, $l1stat, $l2stat, $l3stat);

echo all_equal($arr, 'no_prices');

A quick profile for the answers given thus far, for 1000 iterations on array length 1000:

  array_flip: 0.07321620 seconds
array_unique: 0.32569408 seconds
     foreach: 0.15136194 seconds
array_filter: 0.41404295 seconds

The code used to profile is here: http://codepad.org/szgNfWHe

Note: As @cypherabe rightly points out, array_flip does not overtake array_unique until the array has at least 5 elements, and does not overtake foreach until the array has at least 10 elements.

No, this code won't work:

if (($tstat&&$l1stat&&$l2stat&&$l3stat)=='no_prices')
{
    //do something
}

Why? Because condition in parentheses, will check result itself - You are comparing boolean to string. So in pseudo-code, thats what your code looks like:

if ( ($tstat is true, $l1stat is true, $l2stat is true, $l3stat is true) == 'no_prices' )
     ^                         whole thing returns true                ^    ^   true  ^

If you wan't to achieve this, you can use count() and array_unique():

if ($tstat == 'no_prices' && count(array_unique(array($tstat, $l1stat, $l2stat, $l3stat))) == 1)

Unless I'm mistaken, there's no native way of doing this. If this is something that you have to check for often, try using a custom function for it, e.g.:

function allEquals($chkstr, $vals) {
    if (!is_array($vals)) { die('allEquals() $vals not an array'); }
    foreach ($vals AS $v) {
        if ($chkstr != $v) { return false; }
    }
    return true;
}

In your case you can do:

if (count(array_unique($tstat, $l1stat, $l2stat, $l3stat)) == 1 //Check if all share the same value (i.e., number of unique values is 1
&& $tstat == 'no_prices')) //If everything is the same and $stat == 'no_prices', then everything is 'no_prices'
{

}
<?php
$tstat = $l1stat = $l2stat = $l3stat = 'no_prices';
$testVars = array($tstat,$l1stat,$l2stat,$l3stat);

if(count(array_filter($testVars, function($x) { return $x === 'no_prices'; })) == count($testVars))
{
        print("Correct");
}

Use array_filter with a anonymous callback, and check if its length is greater is equal to original array i.e. all conditions passed,

or if length is greater than zero i.e. any one condition passed

try this:

$arr = array($tstat,$l1stat,...); //make an array
$arr =array_unique($arr);//unique this array

if(count($arr) == 1 && $arr[0] = 'no_prices'){ // check if only one array element have with same value
    echo "got it";
}

demo example

The answer is "no". There's no shorthand to the given condition that will make your code more readable, which should be your top priority. You can improve it though:

define('MYAPP_NO_PRICES', 'no_prices');

if ($tstat === MYAPP_NO_PRICES
        && $l1stat === MYAPP_NO_PRICES
        && $l2stat === MYAPP_NO_PRICES
        && $l3stat === MYAPP_NO_PRICES) {                                 
    // do something
}

Having all these vars to check individually is a code smell; you might want to rethink this design so you never have to do this.

My first idea would go into PHP's Array API:

// $tstadt, $l1stat, … are all "no_prices"
$isAllNoPrice = array_unique(array($tstat, $l1stat, …)) == array("no_prices"));
if ($isAllNoPrice) {
    // …

}

Documentation is mandatory otherwise nobody (including yourself) will understand the code.

If efficiency might be a concern others pointed out that array_unique() seems to be slow. Using the keys of the hash table would be a next approach:

// $tstadt, $l1stat, … are all "no_prices"
$varsMap = array(
    $tstat  => null,
    $l1stat => null,
    // …
);
if (array_keys($varsMap) == array("no_prices")) {
    // …

}

But now the wall of code is growing. PHP offers one operator which nearly does what you want and is chainable: &

$v1 = "no_prices";
$v2 = "no_prices";
$v3 = "no_prices";

var_dump(($v1 & $v2 & $v3) == "no_prices"); // bool(true)

$v3 = "prices";
var_dump(($v1 & $v2 & $v3) == "no_prices"); // bool(false)

I said it nearly does what you want: There are cases in which you will have false positives:

$v1 = 1;
$v2 = 1;
$v3 = 3;

var_dump(($v1 & $v2 & $v3) == 1); // bool(true)

For Strings it seems to cut the bitmask to the shortest string:

$v1 = "abcd";
$v2 = "ab";
$v3 = "abc";

var_dump($v1 & $v2 & $v3); // "ab"
var_dump(($v1 & $v2 & $v3) == "ab"); // bool(true)

So I don't recommend this as a general purpose solution. Only if you know (=unit tested) that your values are in a set where no combination never results to a false positive (e.g. {"dog", "cat", "horse"}) you might consider this solution. I gave it a second thought and must say don't use that at all. Imagine how your colleagues will love you for searching a bug introduced by that method.