Jan
29

Generando IFs con PHP // Lo mas loco que se me ha ocurrido @_@

De verdad que nunca creí llegar a tanto, pero la necesidad de verdad me hizo enloquecer. Aclaro que esto es también para presumir y por favor dejen críticas constructivas, no hago diagramas de flujo a nadie :D (vale la pena seguir leyendo léanlo si quieren o al menos pasen a compadecer mi status de locura momentaneo en los comments :P )

Lo que busco con todo esto que les mostraré, es crear una lista de IF's en la que sólo verifico que cierta variable exista y además contenga algún valor tratando de evitar Warnings al usar variables no declaradas aún, y de ahí un 2do paso que no les mostraré en el cual dentro de un procedimiento genero chorrocientas mil combinaciones de INNER JOIN's y WHERE's en consultas SQL. :S

Si tuviéramos una aplicación en PHP en la que hacemos listado de registros, y en la que intentamos filtrar a su ves por alguna serie de parámetros que le enviemos (por ejemplo en el caso de wordpress el usa algo como isCategory(), isDate(), isPost(), isSearch o cosas así)... Si tuviéramos por ejemplo (como en mi caso algo así):

  1. isSearch()
  2. isType()
  3. isCategory()
  4. isDate()
  5. isOption1()
  6. isOption2()
  7. isOptionEtc()

Tendríamos que hacer tantas validaciones como funciones tenemos, menos 1: (2^7)=128 ¡¡¡128 combinaciones O_O!!! ¿Y si el cliente cambia de opinión y ahora quita o agrega una posibilidad? neeel... Ni loco escribo eso a pata!! safo! :P ... Y sin intensión de asustar a alguien, si así como están las cosas a alguien se le ocurre agregar tan solo una opción, como resultado esta cantidad crecería exponencialmente ufffff!!!

Algo así como esto en términos humanos es lo que necesito hacer:

Sea isSearch() = TRUE y todas las demas FALSE.
Sea isType() = TRUE y todas las demas FALSE.
Sea isCategory() = TRUE y todas las demas FALSE.
...
Sea isOptionEtc() = TRUE y todas las demas FALSE.
...

Y todas las demas combinaciones que pueda hacerse entre ellas, pero si no queda claro, visto de otra forma, siempre hago algo así antes de generar esa lista de combinaciones:

#isSearch()isType()isCategory()isDate()isOption1()isOption2()isOptionEtc()
1FALSEFALSEFALSEFALSEFALSEFALSEFALSE
2FALSEFALSEFALSEFALSEFALSEFALSETRUE
3FALSEFALSEFALSEFALSEFALSETRUEFALSE
4FALSEFALSEFALSEFALSEFALSETRUETRUE
5FALSEFALSEFALSEFALSETRUEFALSEFALSE
6FALSEFALSEFALSEFALSETRUEFALSETRUE
7FALSEFALSEFALSEFALSETRUETRUEFALSE
8FALSEFALSEFALSEFALSETRUETRUETRUE
9FALSEFALSEFALSETRUEFALSEFALSEFALSE
10FALSEFALSEFALSETRUEFALSEFALSETRUE
11FALSEFALSEFALSETRUEFALSETRUEFALSE
12FALSEFALSEFALSETRUEFALSETRUETRUE
13FALSEFALSEFALSETRUETRUEFALSEFALSE
14FALSEFALSEFALSETRUETRUEFALSETRUE
muchas muchas combinaciones mas... =S
125TRUETRUETRUETRUETRUEFALSEFALSE
126TRUETRUETRUETRUETRUEFALSETRUE
127TRUETRUETRUETRUETRUETRUEFALSE
128TRUETRUETRUETRUETRUETRUETRUE

y bueno uff, ahora imaginar la cantidad de IF's que tengo que escribir para validar eso aún mas increíble, por lo que inventé esta plasta de código :p a la que solo hay que pasarle un arreglo con los datos que hay que validar.

php:
/*
 * Define una secuencia de IFs para crear los filtros.
 */

function setFiltros($filtros = array()){
    if(!is_Array($filtros) OR count($filtros)==0)return false;
        $ifs = pow(2,count($filtros))-1;
        ob_start();
        for($val=1;$val< =$ifs;$val++){
                $bin = sprintf("%0".strlen(decbin($ifs))."s",decbin($val));
                echo "/*$bin (".strlen(decbin($ifs)).")*/\n";
                if($val>1)
                    echo "elseif(";
                else
                    echo "if(";
                foreach($filtros as $_v=>$_k){
                        echo ($bin[$_v]?"\$$_k=":'!')."is('$_k')";
                        if($_v!=count($filtros)-1)
                            echo " AND ";
                    }
                echo ")";
                    echo "{\n\t";
                    echo "\$this->setFiltro(array(";
                    $aux = '';
                    foreach($filtros as $_v=>$_k)
                        if($bin[$_v])$aux .= "'$_k'=>\$$_k, ";
                    echo substr($aux,0,strlen($aux)-2);
                    echo "));\n";
                    echo "}";
            }
        eval($out = ob_get_clean());
    }

Esta función no retorna nada. La última línea de la función eval($out = ob_get_clean()) ejecuta todo lo que se generó y lo ejecuta como si fuera código PHP.

Para hacerla funcionar, sólo hay que pasarle como parámetro un arreglo con las distintas opciones que cuento. Por ejemplo:

php:
setFiltros(array('Search','Type','Category','Date','Option1','Option2','OptionEtc'));

O el mismo código visto de otra forma mas fácilmente entendible:

php:
$filtros = array();
$filtros[] = 'Search';
$filtros[] = 'Type';
$filtros[] = 'Category';
$filtros[] = 'Date';
$filtros[] = 'Option1';
$filtros[] = 'Option2';
$filtros[] = 'OptionEtc';

setFiltros($filtros);

Y lo que da como salida es una secuencia de IFs que valida la entrada de datos (Esta es la parte que la función ejecuta como código PHP):

php:
/*0000001 (7)*/
if(!is('Search') AND !is('Type') AND !is('Category') AND !is('Date') AND !is('Option1') AND !is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('OptionEtc'=>$OptionEtc));
}/*0000010 (7)*/
elseif(!is('Search') AND !is('Type') AND !is('Category') AND !is('Date') AND !is('Option1') AND $Option2=is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Option2'=>$Option2));
}/*0000011 (7)*/
elseif(!is('Search') AND !is('Type') AND !is('Category') AND !is('Date') AND !is('Option1') AND $Option2=is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Option2'=>$Option2, 'OptionEtc'=>$OptionEtc));
}/*0000100 (7)*/
elseif(!is('Search') AND !is('Type') AND !is('Category') AND !is('Date') AND $Option1=is('Option1') AND !is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Option1'=>$Option1));
}/*0000101 (7)*/
elseif(!is('Search') AND !is('Type') AND !is('Category') AND !is('Date') AND $Option1=is('Option1') AND !is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Option1'=>$Option1, 'OptionEtc'=>$OptionEtc));
}/*0000110 (7)*/
elseif(!is('Search') AND !is('Type') AND !is('Category') AND !is('Date') AND $Option1=is('Option1') AND $Option2=is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Option1'=>$Option1, 'Option2'=>$Option2));
}/*0000111 (7)*/
elseif(!is('Search') AND !is('Type') AND !is('Category') AND !is('Date') AND $Option1=is('Option1') AND $Option2=is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Option1'=>$Option1, 'Option2'=>$Option2, 'OptionEtc'=>$OptionEtc));
}/*0001000 (7)*/
elseif(!is('Search') AND !is('Type') AND !is('Category') AND $Date=is('Date') AND !is('Option1') AND !is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Date'=>$Date));
}/*0001001 (7)*/
elseif(!is('Search') AND !is('Type') AND !is('Category') AND $Date=is('Date') AND !is('Option1') AND !is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Date'=>$Date, 'OptionEtc'=>$OptionEtc));
}/*0001010 (7)*/
elseif(!is('Search') AND !is('Type') AND !is('Category') AND $Date=is('Date') AND !is('Option1') AND $Option2=is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Date'=>$Date, 'Option2'=>$Option2));
}/*0001011 (7)*/
elseif(!is('Search') AND !is('Type') AND !is('Category') AND $Date=is('Date') AND !is('Option1') AND $Option2=is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Date'=>$Date, 'Option2'=>$Option2, 'OptionEtc'=>$OptionEtc));
}/*0001100 (7)*/
elseif(!is('Search') AND !is('Type') AND !is('Category') AND $Date=is('Date') AND $Option1=is('Option1') AND !is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Date'=>$Date, 'Option1'=>$Option1));
}/*0001101 (7)*/
elseif(!is('Search') AND !is('Type') AND !is('Category') AND $Date=is('Date') AND $Option1=is('Option1') AND !is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Date'=>$Date, 'Option1'=>$Option1, 'OptionEtc'=>$OptionEtc));
}/*0001110 (7)*/
elseif(!is('Search') AND !is('Type') AND !is('Category') AND $Date=is('Date') AND $Option1=is('Option1') AND $Option2=is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Date'=>$Date, 'Option1'=>$Option1, 'Option2'=>$Option2));
}/*0001111 (7)*/
elseif(!is('Search') AND !is('Type') AND !is('Category') AND $Date=is('Date') AND $Option1=is('Option1') AND $Option2=is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Date'=>$Date, 'Option1'=>$Option1, 'Option2'=>$Option2, 'OptionEtc'=>$OptionEtc));
}/*0010000 (7)*/
elseif(!is('Search') AND !is('Type') AND $Category=is('Category') AND !is('Date') AND !is('Option1') AND !is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Category'=>$Category));
}/*0010001 (7)*/
elseif(!is('Search') AND !is('Type') AND $Category=is('Category') AND !is('Date') AND !is('Option1') AND !is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Category'=>$Category, 'OptionEtc'=>$OptionEtc));
}/*0010010 (7)*/
elseif(!is('Search') AND !is('Type') AND $Category=is('Category') AND !is('Date') AND !is('Option1') AND $Option2=is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Category'=>$Category, 'Option2'=>$Option2));
}/*0010011 (7)*/
elseif(!is('Search') AND !is('Type') AND $Category=is('Category') AND !is('Date') AND !is('Option1') AND $Option2=is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Category'=>$Category, 'Option2'=>$Option2, 'OptionEtc'=>$OptionEtc));
}/*0010100 (7)*/
elseif(!is('Search') AND !is('Type') AND $Category=is('Category') AND !is('Date') AND $Option1=is('Option1') AND !is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Category'=>$Category, 'Option1'=>$Option1));
}/*0010101 (7)*/
elseif(!is('Search') AND !is('Type') AND $Category=is('Category') AND !is('Date') AND $Option1=is('Option1') AND !is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Category'=>$Category, 'Option1'=>$Option1, 'OptionEtc'=>$OptionEtc));
}/*0010110 (7)*/
elseif(!is('Search') AND !is('Type') AND $Category=is('Category') AND !is('Date') AND $Option1=is('Option1') AND $Option2=is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Category'=>$Category, 'Option1'=>$Option1, 'Option2'=>$Option2));
}/*0010111 (7)*/
elseif(!is('Search') AND !is('Type') AND $Category=is('Category') AND !is('Date') AND $Option1=is('Option1') AND $Option2=is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Category'=>$Category, 'Option1'=>$Option1, 'Option2'=>$Option2, 'OptionEtc'=>$OptionEtc));
}/*0011000 (7)*/
elseif(!is('Search') AND !is('Type') AND $Category=is('Category') AND $Date=is('Date') AND !is('Option1') AND !is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Category'=>$Category, 'Date'=>$Date));
}/*0011001 (7)*/
elseif(!is('Search') AND !is('Type') AND $Category=is('Category') AND $Date=is('Date') AND !is('Option1') AND !is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Category'=>$Category, 'Date'=>$Date, 'OptionEtc'=>$OptionEtc));
}/*0011010 (7)*/
elseif(!is('Search') AND !is('Type') AND $Category=is('Category') AND $Date=is('Date') AND !is('Option1') AND $Option2=is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Category'=>$Category, 'Date'=>$Date, 'Option2'=>$Option2));
}/*0011011 (7)*/
elseif(!is('Search') AND !is('Type') AND $Category=is('Category') AND $Date=is('Date') AND !is('Option1') AND $Option2=is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Category'=>$Category, 'Date'=>$Date, 'Option2'=>$Option2, 'OptionEtc'=>$OptionEtc));
}/*0011100 (7)*/
elseif(!is('Search') AND !is('Type') AND $Category=is('Category') AND $Date=is('Date') AND $Option1=is('Option1') AND !is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Category'=>$Category, 'Date'=>$Date, 'Option1'=>$Option1));
}/*0011101 (7)*/
elseif(!is('Search') AND !is('Type') AND $Category=is('Category') AND $Date=is('Date') AND $Option1=is('Option1') AND !is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Category'=>$Category, 'Date'=>$Date, 'Option1'=>$Option1, 'OptionEtc'=>$OptionEtc));
}/*0011110 (7)*/
elseif(!is('Search') AND !is('Type') AND $Category=is('Category') AND $Date=is('Date') AND $Option1=is('Option1') AND $Option2=is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Category'=>$Category, 'Date'=>$Date, 'Option1'=>$Option1, 'Option2'=>$Option2));
}/*0011111 (7)*/
elseif(!is('Search') AND !is('Type') AND $Category=is('Category') AND $Date=is('Date') AND $Option1=is('Option1') AND $Option2=is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Category'=>$Category, 'Date'=>$Date, 'Option1'=>$Option1, 'Option2'=>$Option2, 'OptionEtc'=>$OptionEtc));
}/*0100000 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND !is('Category') AND !is('Date') AND !is('Option1') AND !is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type));
}/*0100001 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND !is('Category') AND !is('Date') AND !is('Option1') AND !is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'OptionEtc'=>$OptionEtc));
}/*0100010 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND !is('Category') AND !is('Date') AND !is('Option1') AND $Option2=is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'Option2'=>$Option2));
}/*0100011 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND !is('Category') AND !is('Date') AND !is('Option1') AND $Option2=is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'Option2'=>$Option2, 'OptionEtc'=>$OptionEtc));
}/*0100100 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND !is('Category') AND !is('Date') AND $Option1=is('Option1') AND !is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'Option1'=>$Option1));
}/*0100101 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND !is('Category') AND !is('Date') AND $Option1=is('Option1') AND !is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'Option1'=>$Option1, 'OptionEtc'=>$OptionEtc));
}/*0100110 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND !is('Category') AND !is('Date') AND $Option1=is('Option1') AND $Option2=is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'Option1'=>$Option1, 'Option2'=>$Option2));
}/*0100111 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND !is('Category') AND !is('Date') AND $Option1=is('Option1') AND $Option2=is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'Option1'=>$Option1, 'Option2'=>$Option2, 'OptionEtc'=>$OptionEtc));
}/*0101000 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND !is('Category') AND $Date=is('Date') AND !is('Option1') AND !is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'Date'=>$Date));
}/*0101001 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND !is('Category') AND $Date=is('Date') AND !is('Option1') AND !is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'Date'=>$Date, 'OptionEtc'=>$OptionEtc));
}/*0101010 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND !is('Category') AND $Date=is('Date') AND !is('Option1') AND $Option2=is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'Date'=>$Date, 'Option2'=>$Option2));
}/*0101011 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND !is('Category') AND $Date=is('Date') AND !is('Option1') AND $Option2=is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'Date'=>$Date, 'Option2'=>$Option2, 'OptionEtc'=>$OptionEtc));
}/*0101100 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND !is('Category') AND $Date=is('Date') AND $Option1=is('Option1') AND !is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'Date'=>$Date, 'Option1'=>$Option1));
}/*0101101 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND !is('Category') AND $Date=is('Date') AND $Option1=is('Option1') AND !is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'Date'=>$Date, 'Option1'=>$Option1, 'OptionEtc'=>$OptionEtc));
}/*0101110 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND !is('Category') AND $Date=is('Date') AND $Option1=is('Option1') AND $Option2=is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'Date'=>$Date, 'Option1'=>$Option1, 'Option2'=>$Option2));
}/*0101111 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND !is('Category') AND $Date=is('Date') AND $Option1=is('Option1') AND $Option2=is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'Date'=>$Date, 'Option1'=>$Option1, 'Option2'=>$Option2, 'OptionEtc'=>$OptionEtc));
}/*0110000 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND $Category=is('Category') AND !is('Date') AND !is('Option1') AND !is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'Category'=>$Category));
}/*0110001 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND $Category=is('Category') AND !is('Date') AND !is('Option1') AND !is('Option2') AND $OptionEtc=is('OptionEtc')){
        $this->setFiltro(array('Type'=>$Type, 'Category'=>$Category, 'OptionEtc'=>$OptionEtc));
}/*0110010 (7)*/
elseif(!is('Search') AND $Type=is('Type') AND $Category=is('Category') AND !is('Date') AND !is('Option1') AND $Option2=is('Option2') AND !is('OptionEtc')){
        $this->setFiltro(