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

如何使用关联数组编写良好的PHP数据库插入

  •  10
  • Tom  · 技术社区  · 16 年前

    在PHP中,我想使用字段/值对的关联数组中包含的数据插入数据库。

    $_fields = array('field1'=>'value1','field2'=>'value2','field3'=>'value3');
    

    生成的SQL插入应如下所示:

    INSERT INTO table (field1,field2,field3) VALUES ('value1','value2','value3');
    

    我提出了以下PHP一行程序:

    mysql_query("INSERT INTO table (".implode(',',array_keys($_fields)).") VALUES (".implode(',',array_values($_fields)).")");
    

    implodes 生成逗号分隔的字符串。问题是它不会转义或引用插入数据库的值。为了说明危险,想象一下如果 $_fields

    $_fields = array('field1'=>"naustyvalue); drop table members; --");
    

    将生成以下SQL:

    INSERT INTO table (field1) VALUES (naustyvalue); drop table members; --;
    

    幸运的是 multiple queries are not supported ,但是,引用和转义对于防止SQL注入漏洞至关重要。

    注意:PDO或mysqli准备的查询目前不是我的选项,因为代码库已经广泛使用mysql了-计划进行更改,但转换需要大量资源?

    7 回复  |  直到 16 年前
        1
  •  22
  •   Galen    12 年前

    我唯一要改变的是为了可读性目的而使用sprintf

    $sql = sprintf(
        'INSERT INTO table (%s) VALUES ("%s")',
        implode(',',array_keys($_fields)),
        implode('","',array_values($_fields))
    );
    mysql_query($sql);
    

    并确保值已转义。

        2
  •  3
  •   Frank Farmer    16 年前

    但你要确保 mysql_escape() 并引用您在查询中保留的值,否则您将看到SQL注入漏洞。

    或者,您可以使用参数化查询,在这种情况下,您实际上可以传递数组本身,而不是构建查询字符串。

        3
  •  1
  •   blockhead    16 年前

    最佳实践是使用ORM(条令2.0)、ActiveRecord实现(条令1.0,RedBean)或TableGateway模式实现(Zend_Db_Table,Prope)。这些工具将使您的生活更加轻松,为您处理许多繁重的工作,并帮助您避免SQL注入。

    除此之外,您所做的事情本身并没有什么错误,您可能只是想将其抽象为一个类或一个函数,以便您可以在不同的地方重复该功能。

        4
  •  0
  •   Community Mohan Dere    9 年前

    使用 把格式数据写成串 花招 加伦 在一个 previous answer

    $escapedfieldValues = array_map(create_function('$e', 'return mysql_real_escape_string(((get_magic_quotes_gpc()) ? stripslashes($e) : $e));'), array_values($_fields));
    
    $sql = sprintf('INSERT INTO table (%s) VALUES ("%s")', implode(',',array_keys($_fields)), implode('","    ',$escapedfieldValues));
    
    mysql_query($sql);
    

    magic_quotes_gpc 是开还是关。如果我使用新的PHPV5.3.0,代码可能会更好 anonymous functions 但我需要它在旧的PHP安装上运行。

    此代码比原始代码长一点(也慢一点),但更安全。

        5
  •  0
  •   Marco Demaio    13 年前

    我使用它来检索插入部分的值。 但这可能是一种荒谬的做事方式。欢迎提出意见/建议。

       function arrayToSqlValues($array)
       {
          $sql = "";
          foreach($array as $val)
          {    
             //adding value
             if($val === NULL)
                $sql .= "NULL";
             else
                /*
                useless piece of code see comments
                if($val === FALSE)
                   $sql .= "FALSE";
                else
                */
                   $sql .= "'" . addslashes($val) . "'";
    
             $sql .= ", ";
          };
    
          return "VALUES(" . rtrim($sql, " ,") . ")";
       }
    
        6
  •  0
  •   psycho brm    13 年前

    function implode_sql_values($vals)
    {
        $s = '';
        foreach ($vals as $v)
            $s .= ','.(($v===NULL)?'NULL':'"'.mysql_real_escape_string($v).'"');
    
        return substr($s, 1);
    }
    

    用法:

    implode_sql_values(array_values( array('id'=>1, 'nick'=>'bla', 'fbid'=>NULL) ));
    // =='"1","bla",NULL'
    
        7
  •  0
  •   Marc Ruef    9 年前

    function insertarray($table, $arr){
       foreach($arr as $k => $v){
          $col[] = sanitize($k);
          $val[] = "'".sanitize($v)."'";
       }
    
       query('INSERT INTO '.sanitize($table).' ('.implode(', ', $col).') VALUES ('.implode(', ', $val).')' );
    }