13

そこで、多次元配列に基づいてSQLクエリ文字列を生成する関数を作成しようとしています。

例:

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*/

ご覧のとおり、現在印刷中の3行目についてサポートが必要です。

SELECT ID、ユーザー名FROMテーブルWHERE姓と郵便番号

しかし、それは印刷する必要があります

SELECT ID、ユーザー名FROMテーブルWHERE lastname ='doe' AND zipcode = '12345'

4

9 に答える 9

16

あなたは実際に多次元配列を内破しているのではありません。$conditionsは連想配列です。

関数createQueryString()内でforeachループを使用するだけです。このようなものは機能するはずです、テストされていないことに注意してください。

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

注:SQLインジェクションを防ぐには、使用するDBに適切/必要に応じて、値をエスケープまたは引用符で囲む必要があります。コピーして貼り付けるだけではありません。考える!

于 2010-07-18T18:26:01.613 に答える
10
function implodeItem(&$item, $key) // Note the &$item
{
  $item = $key . "=" . $item;
}

[...]

$conditionals = array(
  "foo" => "bar"
);

array_walk($conditionals, "implodeItem");
implode(' AND ', $conditionals);

テストされていませんが、このようなものは機能するはずです。このようにして、$ itemが配列であるかどうかを確認し、そのような場合にINを使用することもできます。

于 2010-07-18T18:34:01.920 に答える
2

を処理するために別の関数を作成する必要があります$conditionalArray。つまり$key => $value、型を処理して処理します。たとえば、文字列の場合は引用符を適用します。

あなたはただ=状態を扱っていますか?LIKE、、<はどう>ですか?

于 2010-07-18T18:19:26.083 に答える
2

セクシーすぎないなら許して!

 $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'
于 2010-10-07T10:50:31.390 に答える
1

自動化された条件文の作成には反対することをお勧めします。
あなたのケースはあまりにもローカルですが、他の多くの演算子(LIKE、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)...

次に、これらの変数を必要な方法で組み合わせます。2つのオプションがあります。field='value'ペアを使用してこれの別の配列を作成し、それを内包するか、単に連結し、最後にsubstrを追跡しますAND

于 2010-07-18T18:20:33.430 に答える
0

私はこれのバリエーションを使用します:

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;
    }
};

ラフですが動作します。

于 2013-10-16T18:21:40.770 に答える
0

動作するバージョンは次のとおりです。

//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;
    }
}
于 2015-10-24T12:53:01.203 に答える
0

これはpdomysqlタイプの場合ですが、私が行うのはpdoラッパーメソッドをビルドすることです。この場合、文字列のビルドに役立つこの関数を実行します。キーを操作するため、可能な方法はありません。手動で定義/受け入れるキーを知っているので、mysqlinjectに。

このデータを想像してみてください。

           $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_type関数です

于 2016-03-29T12:19:42.773 に答える
-1

これを試して

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);
于 2016-09-21T19:34:18.043 に答える