【问题标题】:How to insert array into MySQL when varchar must be inserted必须插入varchar时如何将数组插入MySQL
【发布时间】:2016-03-28 03:44:33
【问题描述】:

See the image here 我有一个表格收集以下信息:年份(int)、案例编号(varchar)和收到时间(varchar)。由于 year 是数字,我在 MySQL 中设置了 int,然后 Case number 和 Time Received 既有数字又有字母,因此我在 MYSQL 中设置了 varchar。我使用数组是因为我插入了很多记录。我使用 mysql_real_escape_string() 作为数组。但它没有用。如何将包含字母、符号和数字的数组传递到 MySQL 中?谢谢你。

//Output any connection error
if ($mysqli->connect_error) {
die('Error : ('. $mysqli->connect_errno .') '. $mysqli->connect_error);
}
if (isset($_REQUEST['submit']) && isset($_REQUEST['year']) ) {
  foreach ($_REQUEST['year'] as $k=> $value ){ // loop through array

    $year     = $_REQUEST['year'];
    $c_no        = mysql_real_escape_string($_REQUEST['cs']);
    $t_r        = mysql_real_escape_string($_REQUEST['t_r']);


$mysqli->query("INSERT INTO firearms_id_secs (year, case_no, t_received) VALUES 
   ($year[$k], $c_no[$k], $t_r[$k])");
}
}
?>

这是 HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Add more fields using jQuery</title>
<script src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var maxField = 10; //Input fields increment limitation
var addButton = $('.add_button'); //Add button selector
var wrapper = $('.field_wrapper'); //Input field wrapper
var fieldHTML = '<div><input type="text" name="year[]" value="" placeholder="Year"/><input type="text" name="cs[]" value="" placeholder="Case no"/><input type="text" name="t_r[]" value="" placeholder="Time Received"/><a href="javascript:void(0);" class="remove_button" title="Remove field"><img src="remove-icon.png"/></a></div>'; //New input field html 
var x = 1; //Initial field counter is 1
$(addButton).click(function(){ //Once add button is clicked
    if(x < maxField){ //Check maximum number of input fields
        x++; //Increment field counter
        $(wrapper).append(fieldHTML); // Add field html
    }
});
$(wrapper).on('click', '.remove_button', function(e){ //Once remove button is clicked
    e.preventDefault();
    $(this).parent('div').remove(); //Remove field html
    x--; //Decrement field counter
    });
});
</script>
<style type="text/css">
input[type="text"]{height:20px; vertical-align:top;}
.field_wrapper div{ margin-bottom:10px;}
.add_button{ margin-top:10px; margin-left:10px;vertical-align: text-bottom;}
.remove_button{ margin-top:10px; margin-left:10px;vertical-align: text-    bottom;}
</style>
</head>
<body>
<form name="codexworld_frm" action="" method="post">
<div class="field_wrapper">
<div>

        <a href="javascript:void(0);" class="add_button" title="Add field"><img     src="add-icon.png"/></a>
</div>
</div>
<input type="submit" name="submit" value="SUBMIT"/>
</form>
</body>
</html>

【问题讨论】:

  • 最好设置年份 VARCHAR(4) ,案例编号 VARCHAR(255) 和接收时间 DATETIME/TIMESTAMP。只是我的两分钱
  • 谢谢 Willy Pt 是的。嗯,谢谢提醒。我听说了一个数据类型字典,用于正确初始化大小和数据类型的类型。我还需要那个日期时间/时间戳。可以只在 MySQL 中添加新列并将 DATETIME/TIMESTAMP 放在那里吗?
  • @WillyPt 的建议是正确的。您可以使用TIMESTAMP 数据类型并将其默认设置为CURRENT_TIMESTAMP,因此您不需要始终将其包含在查询中,它会自动包含在其中。
  • 是否可以更改 html/javascript 以获得稍微不同的 POST 数据格式?
  • 强烈建议您使用PDO而不是mysqli。

标签: php mysql arrays varchar


【解决方案1】:

提交表单时,_POST(或_REQUEST)将如下所示

array (
  'year' => 
  array (
    0 => '2001',
    1 => '2010',
  ),
  'cs' => 
  array (
    0 => '1',
    1 => '2',
  ),
  't_r' => 
  array (
    0 => '12:00:00',
    1 => '13:00:00',
  ),
  'submit' => 'SUBMIT',
)

如果是这样就更好了

array(
    'records' = array(
        0=>array('year'=>'2001', 'cs'=>'1', 't_r'=>'12:00:00'),
        0=>array('year'=>'2010', 'cs'=>'2', 't_r'=>'13:00:00'),
    ),
)

这需要更改 javascript 代码(我现在太懒了……所以我使用 SPL MultipleIterator 来“模拟”该数据格式)

if ( isset($_POST['submit']) ) {
    // add tests for is_array() POST[year], POST[cs] and POST[t_r]

    // this will make mysqli throw an exception whenever an operation results in an 
    // (mysql) error code other than 0 -> no further error handling included in this script....
    mysqli_report(MYSQLI_REPORT_ALL|MYSQLI_REPORT_STRICT);
    $mysqli = new mysqli('localhost', 'localonly', 'localonly', 'test');

    // create a prepared statement and bind the parameters, see http://docs.php.net/mysqli.quickstart.prepared-statements
    $stmt = $mysqli->prepare('INSERT INTO firearms_id_secs (year, case_no, t_received) VALUES (?,?,?)');
    if ( !$stmt->bind_param('sss', $year, $caseno, $time) ) { // binding all parameters as strings ...let mysql's type system handle it...
        yourErrorHandlerHere(); // or throw an exception....
    }
    // when ever the statement is executed, the current values (at _that_ moment) in $year, $caseno and $time will be used where the ? are in the statement

    // this wouldn't be necessary if the POST body looked like record[1][year]=2001&....
    $mit = new MultipleIterator;
    $mit->attachIterator( new ArrayIterator($_POST['year']) );
    $mit->attachIterator( new ArrayIterator($_POST['cs']) );
    $mit->attachIterator( new ArrayIterator($_POST['t_r']) );

    foreach( $mit as $record ) {
        echo 'executing statement with [', join(',', $record), "]<br/>\r\n";
        // assign the values to the bound parameters
        list($year,$caseno,$time) = $record;
        // and then execute the statement (with those values)

        /*
        you might want to wrap this in a try-catch block, so a single faulty record will not throw off your entire script.
        You might also want to look into transactions (in case a single faulty record is supposed to roll back the entire operation)
        see http://docs.php.net/language.exceptions , http://dev.mysql.com/doc/refman/5.7/en/commit.html
        */
        $stmt->execute();
    }
}

编辑: a) 要允许 NULL 值,您应该在参数中用 NULL 替换空字符串

...
// replace empty strings by NULL
$record = array_map(
    function($e) {
        return 0<strlen(trim($e)) ? $e : NULL;
    },
    $record
);

// assign the values to the bound parameters
list($year,$caseno,$time) = $record;
...

b) 我不知道在这种情况下为什么以及在哪里需要迭代器的键,但是 ....

<?php
$data=array(
    'maj'=>new ArrayIterator(array('A','B','C')),
    'min'=>new ArrayIterator(array('a','b','c')),
    'foo'=>new ArrayIterator(array('do'=>'re', 'mi'=>'fa', 'so'=>'la', 'ti')),
);

$mit = new MultipleIterator(MultipleIterator::MIT_NEED_ANY|MultipleIterator::MIT_KEYS_ASSOC);
$mit->attachIterator( $data['maj'], 'majuscule' );
$mit->attachIterator( $data['min'], 'minuscule' );
$mit->attachIterator( $data['foo'], 'lalala' );

foreach( $mit as $r ) {
    var_export($r);
}

打印

array (
  'majuscule' => 'A',
  'minuscule' => 'a',
  'lalala' => 're',
)array (
  'majuscule' => 'B',
  'minuscule' => 'b',
  'lalala' => 'fa',
)array (
  'majuscule' => 'C',
  'minuscule' => 'c',
  'lalala' => 'la',
)array (
  'majuscule' => NULL,
  'minuscule' => NULL,
  'lalala' => 'ti',
)

【讨论】:

  • 这只是我第一次构建数组类型的表单。所以我真的很困惑。关于 MultipleIterator 的更多信息。我在编码中应用了它。这很有帮助。我读到它说“警告:从 MultipleIterator::key() 返回的非法类型”和 (int)0 的结果作为所有迭代的键。“所以意思是我试着不在表格中放任何东西。然后在 MySQL 中,它变成 0 而不是空白。
【解决方案2】:

确保它是字符串

$c_no        = mysql_real_escape_string("$_REQUEST['cs']");
$t_r        = mysql_real_escape_string("$_REQUEST['t_r']");

$c_no        = mysql_real_escape_string( strval($_REQUEST['cs']) );
$t_r        = mysql_real_escape_string( strval($_REQUEST['t_r']) );

尝试将'' 放入varchar

$mysqli->query("INSERT INTO firearms_id_secs (year, case_no, t_received) 
                VALUES ($year[$k], '$c_no[$k]', '$t_r[$k]')");

【讨论】:

  • 我想我现在看到了问题,我更新了我的答案。看看吧。
  • 你(以及 OP)正在混合 mysql_* 函数和 mysqli。
  • @VolkerK 我从来没想过哈哈。
【解决方案3】:

我将帮助您完成请求的解码部分,其余部分之前已经由@rmondesilva 回答(通过在 VARCHAR 上加上引号)。

$year_param = $_REQUEST['year'];
$case_param = $_REQUEST['cs'];
$time_param = $_REQUEST['t_r'];

if (isset($_REQUEST['submit']) && isset($_REQUEST['year']) ) {

  foreach ($_REQUEST['year'] as $k=> $value ){ // loop through array

    $year     = $year_param[$k];
    $c_no        = mysql_real_escape_string($case_param [$k]);
    $t_r        = mysql_real_escape_string($time_param [$k]);


$mysqli->query("INSERT INTO firearms_id_secs (year, case_no, t_received) VALUES 
   ($year, '$c_no', '$t_r')");
}

考虑在您的项目中使用PDO

【讨论】:

  • 您(以及 OP)正在混合 mysql_* 函数和 mysqli。
  • @VolkerK 我刚刚编辑了他的代码以显示他的逻辑清晰,尽管我确实建议他在答案末尾使用 PDO。我还说我只会帮他解码请求
猜你喜欢
  • 2012-11-09
  • 1970-01-01
  • 2013-03-05
  • 1970-01-01
  • 1970-01-01
  • 2018-02-01
  • 2011-11-10
  • 2011-04-27
  • 1970-01-01
相关资源
最近更新 更多