php - 使用 PDO 创建长插入 SQL 查询的最佳方式

标签 php mysql sql pdo

考虑到我正在构建一个表单并将数据发布到 PHP,一个典型的插入查询对我来说是这样的:

$sql = "INSERT INTO news
            (title, body) 
            VALUES (?, ?)";
$stmt = $db->prepare($sql);
$stmt->execute(array($_POST["title"], $_POST["body"]));
$stmt->closeCursor();

这对于小型查询来说看起来不错,据我所知,这可以让我免受 SQL 注入(inject)之类的攻击。<​​/p>

但是如果我需要使用一个非常大的表单怎么办?像...

$sql = "INSERT INTO ficha_item
    (titulo, tipo_produto, quantidade_peso, unidade_de_venda, 
    unidades_por_caixa, caixas_piso, pisos_palete, tipo_de_palete, 
    unidades_palete, caixas_palete, uni_diametro, uni_largura, 
    uni_profundidade, uni_altura, uni_peso_bruto_unidade, caixa_largura, 
    caixa_profundidade, caixa_altura, altura_palete, volume_unidade, 
    peso_caixa, peso_palete) 
    VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";

我认为计算所有这些问号变得乏味。有没有更简洁的方法来使用 PDO 执行此操作?

最佳答案

我会做这样的事情:

$fields = array(
    'titulo', 
    'tipo_produto', 
    'quantidade_peso', 
    'unidade_de_venda', 
    'unidades_por_caixa', 
    'caixas_piso', 
    'pisos_palete', 
    'tipo_de_palete', 
    'unidades_palete', 
    'caixas_palete', 
    'uni_diametro', 
    'uni_largura', 
    'uni_profundidade', 
    'uni_altura', 
    'uni_peso_bruto_unidade', 
    'caixa_largura', 
    'caixa_profundidade', 
    'caixa_altura', 
    'altura_palete', 
    'volume_unidade', 
    'peso_caixa', 
    'peso_palete'
);
$sql = 'INSERT INTO ficha_item ( %s ) VALUES ( %s )';
// make a list of field names: titulo, tipo_produto /*, etc. */
$fieldsClause = implode( ', ', $fields );
// make a list of named parameters: :titulo, :tipo_produto /*, etc. */
$valuesClause = implode( ', ', array_map( function( $value ) { return ':' . $value; }, $fields ) );
// or, with create_function
$valuesClause = implode( ', ', array_map( create_function( '$value', 'return ":" . $value;' ), $fields ) );
$sql = sprintf( $sql, $fieldsClause, $valuesClause );

// $sql is now something similar to (formatted for display):
// INSERT INTO ficha_item
//     ( titulo, tipo_produto /*, etc. */ )
// VALUES
//     ( :titulo, :tipo_produto /*, etc. */ )

$stmt = $db->prepare($sql);

// if the keys in $_POST match with $fields, you can now simply pass $_POST here
$stmt->execute( $_POST );
// or, as per Bill Karwin's sound suggestion, with the intersection of $_POST
$stmt->execute( array_intersect_key( $_POST, array_flip( $fields ) ) )

换句话说,使用命名参数,并根据 $fields 数组动态生成它们。尽管命名参数不是绝对必要的;它们确实有助于让事情变得更简单,因为传递给例如PDOStatement::execute()的元素的顺序现在不再重要了。

虽然这假设 $_POST 中的元素数量和它们的键与 $sql 中的字段数量和它们的名称完全匹配。

关于php - 使用 PDO 创建长插入 SQL 查询的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14095257/

相关文章:

php - PHP 中的 SQL 数据库连接成功,但我无法查询

mysql - Delphi 和 Web 应用程序之间的行尾问题

php - 时间和 Material 报告 - 组合不同数据类型的多个列和行的过程

mysql - 请帮助使用MySQL来选择要写入的数据需要一个select语句而要创建的记录需要另一个

sql - 按两列值的计数过滤行

php - 通过单击现有图像上传图像

javascript - 如何从使用循环创建的表单中选择设置输入字段的值

php - 使用关系数据库 (mySQL) 的用户可扩展实体的方法

mysql - 将网址存储在 MySQL 中并在 HTML 中显示为链接

sql - 从一个日期列生成 valid_from 和 valid_to 日期