代码之家  ›  专栏  ›  技术社区  ›  st4ck0v3rfl0w

PHP内爆关联数组

  •  12
  • st4ck0v3rfl0w  · 技术社区  · 14 年前

    function createQueryString($arrayToSelect, $table, $conditionalArray) {
    $queryStr = "SELECT ".implode(", ", $arrayToSelect)." FROM ".$table." WHERE ";
    $queryStr = $queryStr.implode(" AND ",$conditionalArray); /*NEED HELP HERE*/
    return $queryStr;
    }
    
    $columnsToSelect = array('ID','username');
    $table = 'table';
    $conditions = array('lastname'=>'doe','zipcode'=>'12345');
    echo createQueryString($columnsToSelect, $table, $conditions); /*will result in incorrect SQL syntax*/
    

    正如你所见,我需要帮助与第三行,因为它目前正在打印

    从表中选择ID,username 姓氏和邮编

    但它应该是印刷品

    从表中选择ID,username

    9 回复  |  直到 12 年前
        1
  •  16
  •   George Marian    12 年前

    实际上你并没有内爆多维数组$条件是关联数组。

    只需在函数createQueryString()中使用foreach循环。像这样的方法应该行得通,注意它没有经过测试

    $terms = count($conditionalArray);
    foreach ($conditionalArray as $field => $value)
    {
        $terms--;
        $queryStr .= $field . ' = ' . $value;
        if ($terms)
        {
            $queryStr .= ' AND ';
        }
    }
    

    转义和/或引用 适用于/必要的DB。不要只是复制和粘贴;想想看!

        2
  •  10
  •   Morfildur    14 年前
    function implodeItem(&$item, $key) // Note the &$item
    {
      $item = $key . "=" . $item;
    }
    
    [...]
    
    $conditionals = array(
      "foo" => "bar"
    );
    
    array_walk($conditionals, "implodeItem");
    implode(' AND ', $conditionals);
    

    未经测试,但像这样的东西应该有用。这样,您还可以检查$item是否是数组,并在这些情况下使用。

        3
  •  2
  •   yclian    14 年前

    $conditionalArray ,即处理 $key => $value 以及处理类型,例如,如果它们是字符串,则应用引号。

    = 条件?那怎么办 LIKE , < , >

        4
  •  2
  •   sakhunzai    14 年前

    如果不是太性感请原谅我!

     $data = array('name'=>'xzy',
                  'zip'=>'3432',
                  'city'=>'NYK',
                  'state'=>'Alaska');
    
    
    $x=preg_replace('/^(.*)$/e', ' "$1=\'". $data["$1"]."\'" ',array_flip($data));
    
    $x=implode(' AND ' , $x);
    

    所以输出会是这样的:

     name='xzy' AND zip='3432' AND city='NYK' AND state='Alaska'
    
        5
  •  1
  •   Your Common Sense    14 年前


    您的案例过于局部,而可能有许多其他操作符,如,IN,BETWEEN,<&燃气轮机;等。
    一些逻辑包括几个and和OR。

    最好的方法是手动方式。
    我总是这样做

    if (!empty($_GET['rooms']))     $w[]="rooms='".mesc($_GET['rooms'])."'";
    if (!empty($_GET['space']))     $w[]="space='".mesc($_GET['space'])."'";
    if (!empty($_GET['max_price'])) $w[]="price < '".mesc($_GET['max_price'])."'";
    

    不过,如果您仍然希望它与这个简单数组一起使用,只需使用

    foreach ($conditions as $fieldname => $value)...
    

    field='value' 配对,然后内爆,或者只是串联,然后substr AND 最后。

        6
  •  0
  •   a coder    11 年前

    function implode_assoc($glue,$sep,$arr)
    {
        if (empty($glue)) {$glue='; ';}
        if (empty($sep)) {$sep=' = ';}
        if (is_array($arr))
        {
            foreach ($arr as $k=>$v)
            {
                $str .= $k.$sep.$v.$glue;
            }
            return $str;
        } else {
            return false;
        }
    };
    

    这很粗糙,但很有效。

        7
  •  0
  •   Mike    9 年前

    以下是一个工作版本:

    //use: implode_assoc($v,"="," / ")
    //changed: argument order, when passing to function, and in function
    //output: $_FILES array ... name=order_btn.jpg / type=image/jpeg / tmp_name=G:\wamp\tmp\phpBDC9.tmp / error=0 / size=0 / 
    
    function implode_assoc($arr,$glue,$sep){
        $str = '';
        if (empty($glue)) {$glue='; ';}
        if (empty($sep)) {$sep=' = ';}
        if (is_array($arr))
        {
            foreach ($arr as $key=>$value)
            {
                $str .= $key.$glue.$value.$sep;
            }
            return $str;
        } else {
            return false;
        }
    }
    
        8
  •  0
  •   Miguel Q    9 年前

    我知道这是针对pdo mysql类型的。。但是我所做的是构建pdo包装方法,在本例中,我做了这个函数来帮助构建字符串,因为我们使用键,所以没有可能的方法来mysql注入,因为我知道我手动定义/接受的键。

               $data=array(
                "name"=>$_GET["name"],
                "email"=>$_GET["email"]
    );
    

    您定义了utils方法。。。

    public static function serialize_type($obj,$mode){
    $d2="";
    if($mode=="insert"){
        $d2.=" (".implode(",",array_keys($obj)).") ";
        $d2.=" VALUES(";
    foreach ($obj as $key=>$item){$d2.=":".$key.",";}
    $d2=rtrim($d2,",").")";}
    
    if($mode=="update"){
        foreach ($obj as $key=>$item){$d2.=$key."=:".$key.",";}    
    }
    return rtrim($d2,",");
    }
    

    然后查询绑定数组生成器(我可以使用直接数组引用,但让我们简化):

      public static function bind_build($array){
         $query_array=$array;
         foreach ($query_array as $key => $value) { $query_array[":".$key] =   $query_array[$key]; unset($query_array[$key]); } //auto prepair array for PDO
    return $query_array;    }
    

    然后你执行。。。

    $query ="insert into table_x ".self::serialize_type( $data, "insert" );
    $me->statement = @$me->dbh->prepare( $query ); 
    $me->result=$me->statement->execute( self::bind_build($data) );
    

    你也可以简单的去更新。。。

      $query ="update table_x set ".self::serialize_type( $data, "update" )." where id=:id";
        $me->statement = @$me->dbh->prepare( $query ); 
    
        $data["id"]="123"; //add the id 
        $me->result=$me->statement->execute( self::bind_build($data) );
    

    但这里最重要的部分是serialize类型函数

        9
  •  -1
  •   David    8 年前

    试试这个

    function GeraSQL($funcao, $tabela, $chave, $valor, $campos) {
        $SQL = '';
    
        if ($funcao == 'UPDATE') :
            //Formata SQL UPDATE
    
            $SQL  = "UPDATE $tabela SET ";
            foreach ($campos as $campo => $valor) :
                $SQL .= "$campo = '$valor', ";
            endforeach;
            $SQL  = substr($SQL, 0, -2);
            $SQL .= " WHERE $chave = '$valor' ";
    
        elseif ($funcao == 'INSERT') :
            //Formata SQL INSERT
    
            $SQL  = "INSERT INTO $tabela ";
    
            $SQL .= "(" . implode(", ", array_keys($campos) ) . ")";
    
            $SQL .= " VALUES ('" . implode("', '", $campos) . "')";         
    
        endif;
    
        return $SQL;
    }
    
    //Use
    $data = array('NAME' => 'JOHN', 'EMAIL' => 'J@GMAIL.COM');
    GeraSQL('INSERT', 'Customers', 'CustID', 1000, $data);