【问题标题】:Parse rows of data from string and insert into database从字符串中解析数据行并插入数据库
【发布时间】:2016-03-22 10:57:39
【问题描述】:

如果这是一个超凡脱俗的问题,我对 PHP 表示歉意。我在 tcp/ip 套接字上接收到一个具有动态长度的数据包。数据包如下所示:

Palace1,radio,location1,location2,location3,location4,GSMId:Palace2,radio,location1,location2,location3,location4,GSMId:Palace3,radio,location1,location2,location3,location4,GSMId

你可以看到GSMId之后我有一个冒号来分隔一个报告。数据包的长度可以是任意长度。

我的任务是我想在每个冒号 (:) 后面切掉这个数据包,并将每个报告保存在数据库中。

现在我要切碎每个数据包是:

$string = "Palace1,radio,location1,location2,location3,location4,GSMId:Palace2,radio,location1,location2,location3,location4,GSMId:Palace3,radio,location1,location2,location3,location4,GSMId";

$countString = substr_count($string, ":");

$NumberOfReports = $countString + 1;

echo $NumberOfReports."\n";
echo $countString."\n";

$chopPacket = explode(':' , $string);

foreach($chopPacket as $value)
{
    $Report = $value;
    echo $Report."\n";
    writeToDataBase($Report);
}

数据库代码:

function writeToDataBase($Report)
{
    date_default_timezone_set("Europe/London");
    $date = date('Y-m-d H:i:s');
    $counter = 0;

    $DecodingData = explode("," , $Report);

    if ($DecodingData > 0) {
        $username = "user";
        $password = "password";
        $host     = "localhost";
    
        $connector = @mysql_connect($host, $username, $password) or die("Unable to connect");
        $selected = @mysql_select_db("gsmdb", $connector) or die("Unable to connect");

        $importSQL = "INSERT INTO gsmclient_test      VALUES('".$counter."','".$DecodingData[0]."','".$DecodingData[1]."','".$DecodingData[2]."','".$DecodingData[3]."','".$DecodingData[4]."', '".$DecodingData[5]."','".$DecodingData[6]."','".$date."')";
        mysql_query($importSQL) or die(mysql_error());
        mysql_close($connector);
    }
}

上面的代码只是将第一个报告保存在数据库中。

【问题讨论】:

  • 您的数据库代码在哪里?一般来说你的代码是正确的,你必须在foreach循环中执行INSERT
  • 请看代码。我在另一个文件中为数据库使用单独的函数。
  • 一般来说没问题,只要在你的函数中做if (count($DecodingData) > 0),因为这是explode()之后的一个数组。还有一个建议 - 开始使用 mysqli_* 函数而不是 mysql_*
  • 还有一件事——$counter 变量的目的是什么?每次调用该函数时,该值将为 0,因此您将尝试使用此 0 插入每条记录。如果这是数据库中唯一的 rowID,则使其自动递增并从 SQL 查询中删除或使其成为全局变量在您的 PHP 脚本中。很可能这就是问题
  • 您应该删除的内容列表以您的数据库代码开头。 mysql_* 函数在当前版本的 PHP 中不存在,并且在 5 年多前已被弃用。停止使用它们。

标签: php regex sql-insert explode preg-split


【解决方案1】:

您需要执行 2 次单独的爆炸来准备数据。

使用单个准备好的语句来确保您的查询稳定且安全。

这里有一个similar mysqli technique 作为比较。

我不喜欢$counter 的样子。您的数据库应将行标识符作为自动递增的主键,date 列的默认值应为 CURRENT_TIMESTAMP,以便在插入查询期间不需要声明该列。

我不知道你的列名是什么,所以我无法将它们添加到我的 sql 中。

我们不应该再看到mysql_ 函数了;使用mysqli_ 或 pdo 函数。

代码:

$string = "Palace1,radio,location1,location2,location3,location4,GSMId:Palace2,radio,location1,location2,location3,location4,GSMId:Palace3,radio,location1,location2,location3,location4,GSMId";

$stmt = $mysqli->prepare("INSERT INTO gsmclient_test VALUES(?,?,?,?,?,?)";
$stmt->bind_param('ssssss', $pal, $rad, $loc1, $loc2, $loc3, $loc4);

foreach (preg_split('/,GSMId:?/', $string, -1, PREG_SPLIT_NO_EMPTY) as $rowString) {
    [$pal, $rad, $loc1, $loc2, $loc3, $loc4] = explode(',', $rowString, 6);
    $stmt->execute();
}

【讨论】:

    猜你喜欢
    • 2018-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多