Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 具有k/v对和未知数的PDO?_Php_Mysql_Oop_Pdo - Fatal编程技术网

Php 具有k/v对和未知数的PDO?

Php 具有k/v对和未知数的PDO?,php,mysql,oop,pdo,Php,Mysql,Oop,Pdo,我有一个关于PDO与数据库对话的问题, 我熟悉的例子是: $data = array('Cathy', '9 Dark and Twisty Road', 'Cardiff'); $STH = $DBH->("INSERT INTO folks (name, addr, city) values (?, ?, ?); $STH->execute($data); 但是,如果我们有一个k/v对,它会是一样的吗?阿拉 $data = array('one'=>'Cath

我有一个关于PDO与数据库对话的问题, 我熟悉的例子是:

$data = array('Cathy', '9 Dark and Twisty Road', 'Cardiff');  

$STH = $DBH->("INSERT INTO folks (name, addr, city) values (?, ?, ?);  
$STH->execute($data); 
但是,如果我们有一个k/v对,它会是一样的吗?阿拉

$data = array('one'=>'Cathy', 'two'=>'9 Dark and Twisty Road', 'three'=>'Cardiff');  

$STH = $DBH->("INSERT INTO folks (?, ?, ?) values (?, ?, ?);  
$STH->execute($data); 
如果我们有一个无法确定的价值量呢

$data = array(range(0, rand(1,99));  

$STH = $DBH->("INSERT INTO folks (/* how would you put stuff here? */) values (/* how would you put stuff here? */);  
$STH->execute($data);  
这让我很困惑

有人能告诉我以上两种方法如何处理k/v对和未知计数吗


非常感谢

准备好的语句只能处理文字,不能处理标识符。因此,您需要使用填充(并正确转义)的标识符构造SQL语句

不过,正确地转义文字是很棘手的。PDO不提供进行文本转义的方法,MySQL的转义文本的方法(使用
`
)与其他数据库和ANSI SQL标准完全不同

如果我们简化了转义标识符的问题,您可以使用如下解决方案:

// assuming mysql semantics
function escape_sql_identifier($ident) {
    if (preg_match('/[\x00`\\]/', $ident)) {
        throw UnexpectedValueException("SQL identifier cannot have backticks, nulls, or backslashes: {$ident}");
    }
    return '`'.$ident.'`';
}

// returns a prepared statement and the positional parameter values
function prepareinsert(PDO $pdo, $table, $assoc) {
    $params = array_values($assoc);
    $literals = array_map('escape_sql_identifier', array_keys($assoc));
    $sqltmpl = "INSERT INTO %s (%s) VALUES (%s)";
    $sql = sprintf($sqltmpl, escape_sql_identifier($table), implode(',',$literals), implode(',', array_fill(0,count($literals),'?'));
    return array($pdo->prepare($sql), $params);
}

function prefixkeys($arr) {
    $prefixed = array();
    for ($arr as $k=>$v) {
        $prefixed[':'.$k] = $v;
    }
    return $prefixed;
}

// returns a prepared statement with named parameters
// this is less safe because the parameter names (keys) may be vulnerable to sql injection
// In both circumstances make sure you do not trust column names given through user input!
function prepareinsert_named(PDO $pdo, $table, $assoc) {
    $params = prefixkeys($assoc);
    $literals = array_map('escape_sql_identifier', array_keys($assoc));
    $sqltmpl = "INSERT INTO %s (%s) VALUES (%s)";
    $sql = sprintf($sqltmpl, escape_sql_identifier($table), implode(',',$literals), implode(', ', array_keys($params)));
    return array($pdo->prepare($sql), $params);
}
$data = array('one'=>'Cathy', 'two'=>'9 Dark and Twisty Road', 'three'=>'Cardiff');
$fields = array_keys($data);
$field_str = '`'.implode('`,`',$fields).'`';
$bind_vals = ':'.implode(',:',$fields);
$sql = 'INSERT INTO tablename ('.$field_str.') VALUES ('.$bind_vals.')';
$sth = $dbh->prepare($sql);
$sth->execute($data);

你不必使用?作为绑定占位符,可以使用:名称和关联数组。然后,您可以将关联数组作为绑定列表传递,PDO现在将使用:binding_名称匹配数组的键。例如,对于关联数组,如果键与数据库中的字段匹配,则可以执行以下操作:

// assuming mysql semantics
function escape_sql_identifier($ident) {
    if (preg_match('/[\x00`\\]/', $ident)) {
        throw UnexpectedValueException("SQL identifier cannot have backticks, nulls, or backslashes: {$ident}");
    }
    return '`'.$ident.'`';
}

// returns a prepared statement and the positional parameter values
function prepareinsert(PDO $pdo, $table, $assoc) {
    $params = array_values($assoc);
    $literals = array_map('escape_sql_identifier', array_keys($assoc));
    $sqltmpl = "INSERT INTO %s (%s) VALUES (%s)";
    $sql = sprintf($sqltmpl, escape_sql_identifier($table), implode(',',$literals), implode(',', array_fill(0,count($literals),'?'));
    return array($pdo->prepare($sql), $params);
}

function prefixkeys($arr) {
    $prefixed = array();
    for ($arr as $k=>$v) {
        $prefixed[':'.$k] = $v;
    }
    return $prefixed;
}

// returns a prepared statement with named parameters
// this is less safe because the parameter names (keys) may be vulnerable to sql injection
// In both circumstances make sure you do not trust column names given through user input!
function prepareinsert_named(PDO $pdo, $table, $assoc) {
    $params = prefixkeys($assoc);
    $literals = array_map('escape_sql_identifier', array_keys($assoc));
    $sqltmpl = "INSERT INTO %s (%s) VALUES (%s)";
    $sql = sprintf($sqltmpl, escape_sql_identifier($table), implode(',',$literals), implode(', ', array_keys($params)));
    return array($pdo->prepare($sql), $params);
}
$data = array('one'=>'Cathy', 'two'=>'9 Dark and Twisty Road', 'three'=>'Cardiff');
$fields = array_keys($data);
$field_str = '`'.implode('`,`',$fields).'`';
$bind_vals = ':'.implode(',:',$fields);
$sql = 'INSERT INTO tablename ('.$field_str.') VALUES ('.$bind_vals.')';
$sth = $dbh->prepare($sql);
$sth->execute($data);
将处理未知数量的名称/值对。不知道插入要使用哪些字段名是不可能的。这个例子也适用于?作为绑定占位符。因此,您可以重复以下内容,而不是名称:

$bind_vals = str_repeat('?,', count($data));
$sql = 'INSERT INTO tablename ('.$field_str.') VALUES ('.$bind_vals.')';

你能解释一下,
$assoc
是做什么用的,以及它是如何使用的吗?
$assoc
是你在文章中描述的
'columnname'=>'columnvalue'
的关联数组!好吧,那么我不知道什么是
$pdo
,我想(出于愚蠢的原因…)那是数组的入口点
$pdo
pdo
对象,你称之为
$DBH
。请注意
$pdo->prepare()
的用法。在开始动态构造SQL之前,您可能希望首先熟悉基本的PDO用法。