Dinamik Hazırlanmış Tablolar Kötü musunuz?

2 Cevap php

Ben Dinamik SQL esneklik gibi ve ben Hazırlanan Tabloların güvenlik + gelişmiş performans gibi. Peki ben gerçekten istiyorum bind_param ve bind_result argümanları "sabit" numarayı kabul çünkü yapmak için zahmetli Dinamik Hazırlanmış anlatımlar vardır. Yani bu sorunu aşmanın bir eval () ifadesi kullandı. Ama bu kötü bir fikir olduğu hissine kapılıyorsunuz. Burada ne demek istediğimi örnek kod

// array of WHERE conditions
$param = array('customer_id'=>1, 'qty'=>'2');
$stmt = $mysqli->stmt_init();

$types = ''; $bindParam = array(); $where = ''; $count = 0;

// build the dynamic sql and param bind conditions
foreach($param as $key=>$val)
{
    $types .= 'i';
    $bindParam[] = '$p'.$count.'=$param["'.$key.'"]'; 
    $where .= "$key = ? AND ";
    $count++;
}

// prepare the query -- SELECT * FROM t1 WHERE customer_id = ? AND qty = ?
$sql = "SELECT * FROM t1 WHERE ".substr($where, 0, strlen($where)-4);
$stmt->prepare($sql);

// assemble the bind_param command
$command = '$stmt->bind_param($types, '.implode(', ', $bindParam).');';

// evaluate the command -- $stmt->bind_param($types,$p0=$param["customer_id"],$p1=$param["qty"]);
eval($command);

Bu son eval () deyimi kötü bir fikir mi? Ben değişken adı $ param arkasında değerleri kapsülleştirip kod enjeksiyonu önlemek için çalıştı.

Herkes bir görüş ya da başka bir öneriniz var mı? Ben farkında olması gereken konular var mı?

2 Cevap

Ben burada eval() kullanmak tehlikeli olduğunu düşünüyorum.

Bu deneyin:

  • soru işaretleri "SELECT * FROM t1 WHERE p1 = ? AND p2 = ?" ile SQL dizesi oluşturmak için params dizi yineleme
  • çağrı prepare() Bu konuda
  • call_user_func_array() dinamik params dizisi geçirerek, bind_param() için arama yapmak için kullanabilirsiniz.

Kodu:

call_user_func_array(array($stmt, 'bind_param'), array($types)+$param);

Her zaman mysql_real_escape_string () kullanabilirsiniz, çünkü gerçekten, hazırlanmış tablolar ve bağlı argümanlar gerekmez. Ve haklısın; dinamik olarak oluşturulan SQL çok daha esnek ve değerlidir.

Burada düzenli mysql_ * arayüzünü kullanarak basit bir örnek:

// Array of WHERE conditions
$conds = array("customer_id" => 1, "qty" => 2);

$wherec = array("1");
foreach ($conds as $col=>$val) $wherec[] = sprintf("`%s` = '%s'", $col, mysql_real_escape_string($val));

$result_set = mysql_query("SELECT * FROM t1 WHERE " . implode(" AND ", $wherec);

Tabii ki, bu basit bir örnek ve yararlı bir sürü oluşturmak ve geliştirmek zorunda yapmak için, ama bu fikirleri gösterir ve bu gerçekten çok çok kullanışlı. Örneğin, burada bir ilişkisel dizi ve tamamen SQL enjeksiyon kasa gelen değerlerle doldurulmuş sütunları ile, keyfi bir tabloya yeni bir satır eklemek için tamamen genel fonksiyonudur:

function insert($table, $record) {
    $cols = array();
    $vals = array();
    foreach (array_keys($record) as $col) $cols[] = sprintf("`%s`", $col);
    foreach (array_values($record) as $val) $vals[] = sprintf("'%s'", mysql_real_escape_string($val));

    mysql_query(sprintf("INSERT INTO `%s`(%s) VALUES(%s)", $table, implode(", ", $cols), implode(", ", $vals)));
}

// Use as follows:
insert("customer", array("customer_id" => 15, "qty" => 86));