PHP MYSQL 在 FOR 循环中插入语句挂起

发布于 2024-12-21 10:40:14 字数 3515 浏览 0 评论 0原文

我花了很多时间进行调试,并在互联网上搜索这个不寻常问题的解决方案。事情是这样的:

我正在开发工单提交和跟踪系统。涉及两个数据库:

  1. 提交数据发布的数据库,位于同一台物理机上,但与服务 php 的 Web 服务器位于单独的虚拟机上。它们位于同一 C 类子网上。
  2. 我们的跟踪系统的数据库。位于不同IP上的不同物理服务器上,也是虚拟机。

我们的工单系统允许存储在数组中的多个“请求的服务”。在我们的提交数据库中,这存储为逗号分隔的字符串,即“40,60,70”,但在我们的跟踪系统数据库中,每个“请求的服务”需要一个单独的条目,以便允许项目的不同方面由不同的工作人员在不同的时间跟踪和完成。

问题是:当我将第二个插入语句(即发往跟踪数据库的语句)放在 for 循环中时,它完全挂起,并且在通过代码中的该点并发送确认之前可能需要 5 到 15 分钟电子邮件。数据也不会被插入。

当我将其从 for 循环中取出并简单地在提交数据库中执行一项插入并在跟踪系统中执行一项插入时,它工作得很好。

首先,我将发布有效的代码,但只向跟踪系统发布一个“服务”:

 public function insertOrder()
{
    $services = implode( ',', $this->model->chk );
    $curdate = $this->model->getMySQLDate( $this->model->curdate );
    $dueDate = $this->model->getMySQLDate( $this->model->dueDate );

    $sql = "INSERT INTO orders VALUES(DEFAULT,
            {$this->sanitize($services)},
            {$this->sanitize($curdate)},
            {$this->sanitize($this->model->submittedBy)},
            {$this->sanitize($this->model->shortDesc)},
            {$this->sanitize($this->model->projDetails)},
            {$this->sanitize($dueDate)},
            {$this->sanitize($this->model->dueDateNotes)},
            {$this->sanitize( $this->model->approveBy)},
            {$this->sanitize( $this->model->cost )} )";

    $this->execute( $sql );

    $this->convertServicesToTracks();
    $notes = $this->model->getTracksNotes();
    $dueDate = $dueDate.' 12:00:00';
    $shortDescNoQuotes = str_replace("\"","'",$this->model->shortDesc);

    $sqlTracks = "INSERT INTO todos VALUES(DEFAULT,
            {$this->sanitizeTracks($this->model->chk[0])},
            NULL,
            {$this->sanitizeTracks($shortDescNoQuotes)},
            {$this->sanitizeTracks($notes)},
            now(),
            {$this->sanitizeTracks($dueDate)},
            NULL,
            12,
            NULL,
            'active',
            NULL,
            now() );";

    //echo $sqlTracks;

    $this->executeTracks( $sqlTacks );
}    private function executeTracks( $sql )
{
    $db = $this->getTracksDB( );


    $this->check4Error( $db, $sql );

    return $result;
}

private function getTracksDB()
{
    if (!$this->tracksdb) $this->tracksdb = new mysqli(AbstractSQL::TRACKS_HOST, AbstractSQL::USER, AbstractSQL::PASS, AbstractSQL::TRACKS_SCHEMA);
    return $this->tracksdb;
}

private function convertServicesToTracks()
{
   //converts submission data to tracking system data
}



private function sanitizeTracks($arg)
{
    if (!isset($arg)) return "NULL";
    if (is_numeric($arg) && !is_double( $arg) ) return $arg;
    return "'{$this->getTracksDB()->escape_string($arg)}'";
}

当我在第二个 INSERT 语句周围添加这个简单的 for 循环时,它会挂起,即使数组只有一项!

    for($i = 0; $i < count($this->model->chk); ++$i)
    {
        $sqlTracks = "INSERT INTO todos VALUES(DEFAULT,
            {$this->sanitizeTracks($this->model->chk[$i])},
            NULL,
            {$this->sanitizeTracks($shortDescNoQuotes)},
            {$this->sanitizeTracks($notes)},
            now(),
            {$this->sanitizeTracks($dueDate)},
            NULL,
            12,
            NULL,
            'active',
            NULL,
            now() );";

    //echo $sqlTracks;

    $this->executeTracks( $sqlTacks );
    }

任何帮助将不胜感激。我对长代码片段表示歉意!

I have spent many hours debugging, and scouring the internet for a solution to this unusual problem. Heres the deal:

I am working on a Work Order Submission and Tracking system. There are two databases involved:

  1. The database where the submissions data gets posted, which is located on the same physical machine, but on a separate virtual machine as the webserver serving the php. They are on the same class C subnet.
  2. The database of our tracking system. Located on a different physical server on a different IP altogether, also a virtual machine.

Our work order system allows for multiple 'services requested', stored in an array. In our sumbissions database, this is stored as a comma separated string, i.e. "40,60,70" but in our tracking system database, each 'service requested' needs a separate entry, as to allow the different aspects of the project to be tracked and completed at different times, by different staff.

THE PROBLEM IS: When I place my second insert statement, the one destined for the tracking database, in a for loop, it completely hangs, and takes maybe 5 to 15 minutes, before it passes that point in the code, and sends the confirmation email. The data does not get inserted either.

When I take it out of the for loop and simply do one insert in the submissions database and one insert into the tracking system, it works fine.

First, Ill post the code that works, but only posts one 'service' to the tracking system:

 public function insertOrder()
{
    $services = implode( ',', $this->model->chk );
    $curdate = $this->model->getMySQLDate( $this->model->curdate );
    $dueDate = $this->model->getMySQLDate( $this->model->dueDate );

    $sql = "INSERT INTO orders VALUES(DEFAULT,
            {$this->sanitize($services)},
            {$this->sanitize($curdate)},
            {$this->sanitize($this->model->submittedBy)},
            {$this->sanitize($this->model->shortDesc)},
            {$this->sanitize($this->model->projDetails)},
            {$this->sanitize($dueDate)},
            {$this->sanitize($this->model->dueDateNotes)},
            {$this->sanitize( $this->model->approveBy)},
            {$this->sanitize( $this->model->cost )} )";

    $this->execute( $sql );

    $this->convertServicesToTracks();
    $notes = $this->model->getTracksNotes();
    $dueDate = $dueDate.' 12:00:00';
    $shortDescNoQuotes = str_replace("\"","'",$this->model->shortDesc);

    $sqlTracks = "INSERT INTO todos VALUES(DEFAULT,
            {$this->sanitizeTracks($this->model->chk[0])},
            NULL,
            {$this->sanitizeTracks($shortDescNoQuotes)},
            {$this->sanitizeTracks($notes)},
            now(),
            {$this->sanitizeTracks($dueDate)},
            NULL,
            12,
            NULL,
            'active',
            NULL,
            now() );";

    //echo $sqlTracks;

    $this->executeTracks( $sqlTacks );
}    private function executeTracks( $sql )
{
    $db = $this->getTracksDB( );


    $this->check4Error( $db, $sql );

    return $result;
}

private function getTracksDB()
{
    if (!$this->tracksdb) $this->tracksdb = new mysqli(AbstractSQL::TRACKS_HOST, AbstractSQL::USER, AbstractSQL::PASS, AbstractSQL::TRACKS_SCHEMA);
    return $this->tracksdb;
}

private function convertServicesToTracks()
{
   //converts submission data to tracking system data
}



private function sanitizeTracks($arg)
{
    if (!isset($arg)) return "NULL";
    if (is_numeric($arg) && !is_double( $arg) ) return $arg;
    return "'{$this->getTracksDB()->escape_string($arg)}'";
}

When I add this simple for loop around the second INSERT statement, it hangs, even if the array only has one item!

    for($i = 0; $i < count($this->model->chk); ++$i)
    {
        $sqlTracks = "INSERT INTO todos VALUES(DEFAULT,
            {$this->sanitizeTracks($this->model->chk[$i])},
            NULL,
            {$this->sanitizeTracks($shortDescNoQuotes)},
            {$this->sanitizeTracks($notes)},
            now(),
            {$this->sanitizeTracks($dueDate)},
            NULL,
            12,
            NULL,
            'active',
            NULL,
            now() );";

    //echo $sqlTracks;

    $this->executeTracks( $sqlTacks );
    }

Any help would be greatly appreciated. And I apologize for the long code snippets!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

野の 2024-12-28 10:40:14

它是通过 for 循环迭代吗?我看到你有回声,那写了什么吗?它必须迭代多少项? 5 分钟似乎很长,但如果有很多物品,可能就是花费这么长时间的原因。您在日志中看到任何错误吗?

您可能会尝试将计数保存在变量中,这样就不必每次都进行计算。它可能会加速你的 for 循环,但我不确定它会插入数据。

for($i = 0, $count = count($this->model->chk); $i < $count; ++$i)
    {
        $sqlTracks = "INSERT INTO todos VALUES(DEFAULT,
            {$this->sanitizeTracks($this->model->chk[$i])},
            NULL,
            {$this->sanitizeTracks($shortDescNoQuotes)},
            {$this->sanitizeTracks($notes)},
            now(),
            {$this->sanitizeTracks($dueDate)},
            NULL,
            12,
            NULL,
            'active',
            NULL,
            now() );";

    //echo $sqlTracks;

    $this->executeTracks( $sqlTacks );
    }

我在 PHP for 循环参考中找到了这个: http://php.net/manual /en/control-structs.for.php

Is it iterating through the for loop? I see you have an echo, did that write anything out? How many items does it have to iterate through? 5 min seems like a long time but if there are a lot of items that could be why it's taking so long. Are you seeing any errors in your logs?

Something you might try is hold the count in a variable so it doesn't have to calculate that each time. It might speed up your for loop but I'm not sure it will insert the data.

for($i = 0, $count = count($this->model->chk); $i < $count; ++$i)
    {
        $sqlTracks = "INSERT INTO todos VALUES(DEFAULT,
            {$this->sanitizeTracks($this->model->chk[$i])},
            NULL,
            {$this->sanitizeTracks($shortDescNoQuotes)},
            {$this->sanitizeTracks($notes)},
            now(),
            {$this->sanitizeTracks($dueDate)},
            NULL,
            12,
            NULL,
            'active',
            NULL,
            now() );";

    //echo $sqlTracks;

    $this->executeTracks( $sqlTacks );
    }

I found this in the PHP for loop reference: http://php.net/manual/en/control-structures.for.php

捶死心动 2024-12-28 10:40:14

好吧,这可能不是问题,但是您通常不应该使用 foreach 循环来避免命中数组中可能不存在的部分吗? 此处有更多相关信息。如果循环遍历空索引,则会破坏 SQL 语句。像这样:

foreach($this->model->chk as $val)

Well, this may not be the problem, but shouldn't you generally use a foreach loop to avoid hitting parts of the array that may not exist? There is more about this here. If you loop through an empty index, it would break your SQL statement. Like this:

foreach($this->model->chk as $val)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文