php - vacio - ¿Cómo puedo verificar si solo una de cada tres variables no está vacía?
optimizar consultas lentas mysql (8)
Tengo tres variables:
$var1
$var2
$var3
En realidad, estoy buscando la mejor manera de verificar si solo una de estas tres variables no está vacía y las otras dos están vacías.
¿Es posible hacer esto con uno solo? Si no, ¿cuál es la mejor manera?
Todas las variables contienen texto.
Bitwise XOR es ideal para esto:
$var1 ^ $var2 ^ $var3
Es posible que tenga problemas si las variables no se convierten en boolean fácilmente, en cuyo caso deberá hacer un empty($var)
en cada una de ellas.
Auge. Cero if
s.
Actualizar
Vaya, si no están todos vacíos, true ^ true ^ true == true
Tendrás que verificar que todos ellos sean ciertos:
($var1 ^ $var2 ^ $var3) && !($var1 && $var2 && $var3)
Esta es una situación en la que debes usar arreglos. Ahora solo tienes 3 valores, pero ¿qué pasa si necesitas 4? ¡Tendrás que cambiar todo tu código!
$var = array();
$var[] = ''abc'';
$var[] = '''';
$var[] = 0;
// will return 1, empty values, false or 0 (falsy values) will not get counted:
echo count(array_filter($var)).'' values found'';
if( count(array_filter($var))==1 ){ echo ''exactly one value set''; }
Si necesita chekear cero o cadenas vacías , puede usar otros métodos para contar . El principio principal de este código es que si agrega más valores, la lógica en sí no necesita cambiarse.
Los valores booleanos devuelven 0 y 1 con array_sum ()
if (array_sum(array(empty($var1), empty($var2), empty($var3))) == 1)
{
echo "one is empty" ;
}
ETA: Esta es una forma más simple:
if (!empty($var1) + !empty($var2) + !empty($var3) == 1) {
echo "1 is not empty" ;
}
ETA 2: No necesitamos los signos negativos.
if (empty($var1) + empty($var2) + empty($var3) == 2) {
echo "1 is not empty" ;
}
Prueba este:
if (($var1 !== '''' && $var2 == '''' && $var3 == '''') ||
($var2 !== '''' && $var1 == '''' && $var3 == '''') ||
($var3 !== '''' && $var1 == '''' && $var2 == '''')) {
echo ''variable is empty'';
}
Prueba esto:
$temp_array = array($var1,$var2,$var3);
$temp_count = count(array_filter($temp_array, ''strlen''));
if($temp_count ==1){
echo "1 variable is not empty";
}
else
{
echo "total empty variable is = ".$temp_count;
}
Puede convertir la variable en una matriz y excluir las variables vacías usando array_filter()
. Luego usa count()
después del filtro.
if(count(array_filter(array($var1,$var2,$var3)))==1){
//only 1 variable is not empty
}
Compruebe el enlace Fiddle
Usaría XOR
( exclusivo o ) para esto, porque está destinado a este propósito, por lo que usar una solución sucia con una matriz no es tan fácil de entender.
if (!(!empty($var1) && !empty($var2) && !empty($var3)) && (!empty($var1) ^ !empty($var2) ^ !empty($var3))) {
echo "Only one string is not empty/n";
}
Y es un 25% más rápido que la respuesta aceptada.
$before = microtime(true);
for ($i = 0; $i < 100000; ++$i) {
$var1 = ''Hello'';
$var2 = '''';
$var3 = '''';
if (!(!empty($var1) && !empty($var2) && !empty($var3)) && (!empty($var1) ^ !empty($var2) ^ !empty($var3))) {
echo "Only one string is not empty/n";
}
$var4 = '''';
$var5 = '''';
$var6 = '''';
if (!(!empty($var4) && !empty($var5) && !empty($var6)) && (!empty($var4) ^ !empty($var5) ^ !empty($var6))) {
echo "Only one string is not empty/n";
}
$var7 = ''Hello'';
$var8 = ''World'';
$var9 = ''!'';
if (!(!empty($var7) && !empty($var8) && !empty($var9)) && (!empty($var7) ^ !empty($var8) ^ !empty($var9))) {
echo "Only one string is not empty/n";
}
}
$after = microtime(true);
echo ($after-$before)/$i . " sec for XOR/n";
// 3.2943892478943E-6 sec for XOR
$before = microtime(true);
for ($i = 0; $i < 100000; ++$i) {
$var1 = ''Hello'';
$var2 = '''';
$var3 = '''';
if (count(array_filter(array($var1, $var2, $var3))) == 1) {
echo "Only one string is not empty/n";
}
$var4 = '''';
$var5 = '''';
$var6 = '''';
if (count(array_filter(array($var4, $var5, $var6))) == 1) {
echo "Only one string is not empty/n";
}
$var7 = ''Hello'';
$var8 = ''World'';
$var9 = '''';
if (count(array_filter(array($var7, $var8, $var9))) == 1) {
echo "Only one string is not empty/n";
}
}
$after = microtime(true);
echo ($after-$before)/$i . " sec for Arrays/n";
// 4.3078589439392E-6 sec for Arrays
* Tuve que actualizar la respuesta porque el nombre "exclusivo o" es algo engañoso en el contexto de más de dos expresiones. Por supuesto, todos los comentaristas tienen razón y son exclusivos o es una operación binaria que se resuelve de izquierda a derecha. 1 ^ 1 ^ 1 == 1
resuelve en 0 ^ 1 == 1
y por lo tanto es true
. Exclusivo o realmente busca un número impar de pistas.
Actualicé mi respuesta con una solución alternativa fácil de leer, pero esto definitivamente no me satisface y tengo que saber que resolví una gran idea errónea de los operadores booleanos en mi mente. La última vez fue una suposición errónea de que AND
y OR
se resolvieron de izquierda a derecha en lugar de primero AND
luego OR
. *