【问题标题】:PHP Batch upload array dataPHP批量上传数组数据
【发布时间】:2021-01-03 19:16:40
【问题描述】:

我正在使用没有批量功能的客户端 API(主 API)。

我从 2 个不同的 API(客户端 API)获取数据并将其合并到一个格式正确的 JSON 文件中。签入在线 JSON Validator。

JSON 文件是 1100 条合并客户数据的记录。一次记录一条记录,我已经构建了一个函数,可以成功地将数据提交到主 API。

我现在已经构建了一个 PHP 脚本,该脚本循环遍历 JSON 文件并获取行数据(每个客户端记录)并将其成功提交到主 API。大约 90 行后,PHP 脚本超时。

我在页面上设置了如下代码

@ini_set('zlib.output_compression', 0);
@ini_set('implicit_flush', 1);
set_time_limit(600);
@ob_end_clean();

并且正在缓冲每个更新以返回从主 API 返回的 JSON 状态代码。

我应该怎么做才能让 PHP 在大约 100 条记录后不超时并不断更新页面上的缓冲区响应?

提前致谢。

杰森

【问题讨论】:

  • 尝试使用 Guzzle 等众多请求库之一并行运行对主 API 的 1100 记录更新。

标签: php timeout


【解决方案1】:

过去,我对这类问题采取了几种不同的方法。唯一的快速 解决方法是,如果您可以更改服务器上的 php.ini 设置以增加超时时间以使您的批处理完成。这不是一个很好的解决方案,但它是一个解决方案。

下一个选项(按工作量的升序排列)是在浏览器和服务器之间建立一个循环,您的浏览器在其中发出请求,服务器发送一部分记录,然后返回浏览器,光标指示在进程停止的地方,浏览器向服务器发出另一个请求,将光标作为参数发送回,并一直持续到批处理完成。这很好,因为您可以向用户显示进度条。

最后,您可以在服务器上运行一个代理,等待提交批处理作业并在 HTTP 请求生命周期之外完全运行它们。因此,您的浏览器发出启动批处理作业的请求,这会导致数据库中的某种记录可以跟踪作业的状态。代理在工作时接起作业并将其设置为挂起状态,然后在完成时设置完成状态。您可以设置一些设置,允许您定期从浏览器轮询服务器,以便在进程完成时提醒用户。当批处理完成时,您可以让代理向用户发送电子邮件报告。这是最可靠的选择,中断处理的风险最小,而且它可以毫不费力地留下审计线索。但设置起来显然更复杂。

【讨论】:

    【解决方案2】:

    谢谢罗。

    您的回复让我朝着正确的方向前进。

    我在前端使用了您的后端想法。我只是一次循环浏览 20 条记录,然后通过 javascript 刷新页面并从 21 到 40 等开始。为了好玩,还添加了一个进度条。

    感谢您帮助我理解这个想法。这不是正确的方法,但我的 Python 和我的 PHP 一样糟糕。

    <?php
    @ini_set('zlib.output_compression', 0);
    @ini_set('implicit_flush', 1);
    set_time_limit(600);
    @ob_end_clean();
    
    require("header.php");
    require_once('nav.php');
    
    function sync_systems($sfData){
    
        $dataPost = $sfData;
        $postID = $dataPost['ID'];
        
    
        $epcall = update_profile($dataPost);
       
        $epResult = json_decode($epcall, true);
        if($epResult['status'] != 404){
            
            
            $sfStatus = updateSFOpportunity($epResult['client_id'], $epResult['ep_id'] );
            
            if($sfStatus == 1){
            $datamsg = " Success! The sync was a success in both Salesforce and other system. OtherSystem Record " . $epResult['ep_id'] . " was created or updated.<br/>";
            } else {
                $datamsg = " Success! The sync was a success in other system, but failed in Salesforce<br/>";
            }
                echo json_encode(['code'=>200, 'msg'=>$datamsg]);
        } else {
            $datamsg = " Failure! The sync did not work.<br/>";
                echo json_encode(['code'=>404, 'msg'=>$datamsg]);
        } // end epResult
    
    
    
    
    }
    
    function sync_ep($sfData){
    
        $dataPost = $sfData;
        $postID = $dataPost['ID'];
        
    
        $epcall = update_profile($dataPost);
       
        $epResult = json_decode($epcall, true);
        if($epResult['status'] != 404){
            
            
        //  $sfStatus = updateSFOpportunity($epResult['client_id'], $epResult['ep_id'] );
            
            if($sfStatus == 1){
            $datamsg = " Success! The sync was a success in both Salesforce and other system. Other System Record " . $epResult['ep_id'] . " was created or updated.<br/>";
            } else {
                $datamsg = " Success! The sync was a success in other system, but failed in Salesforce<br/>";
            }
                echo json_encode(['code'=>200, 'msg'=>$datamsg]);
        } else {
            $datamsg = " Failure! The sync did not work.<br/>";
                echo json_encode(['code'=>404, 'msg'=>$datamsg]);
        } // end epResult
    
    
    
    
    }
    
    
    $ju = "CustomerData20Fall.json";
     
    
    //read json file from url in php
    $readJSONFile = file_get_contents($ju);
     
    //convert json to array in php
    $jfile = json_decode($readJSONFile);
    //print_r($jfile);
    //convert json to array in php
    
    $epSync = array();
    $oldValue = 0;
    $total = count($jfile );
    
    ?>
    <!-- Progress bar holder -->
    <div id="progress" style="width:500px;border:1px solid #ccc;"></div>
    <!-- Progress information -->
    <div id="information" style="width"></div>
    <?php
    
    if(isset($_REQUEST["NEXTVALUE"])){
        $nextValue = $_REQUEST["NEXTVALUE"];
    } else {
        $nextValue = 1;
    }
    
    $refreshValue = $nextValue + 20;
    $displaycounter = $nextValue;
    $timeRemaining = 0;
    $updatedRecords = 0;
    
    foreach ($jfile as $key => $jsons) {
        $newKey = $key;
        if($oldValue != $newKey){
            
            if($newKey >= $nextValue  && $newKey < $refreshValue){
            
                //  echo "Updated: " . [$oldValue]['EPID'] . "<br/>";
                //  echo "<hr>" . $nextValue . " >= " . $newKey . " < " . $refreshValue;
                print_r($epSync[$oldValue]); 
            
                $displaycounter = $newKey;
                
                echo sync_systems($epSync[$oldValue]);
                
                usleep(30000);
                
                flush();
                
                } else {
                if($key == ($refreshValue)){
                    
                
                $theURL = "sf-ep-sync.php?NEXTVALUE=" . $refreshValue . "&RAND=" . rand();
                //  echo "<hr>"  . $newKey . " = " . $refreshValue . " " . $theURL ."<br/>";
                
                echo "<script>location.href = '" . $theURL . "';</script>";
                exit;
                
                    
                }
            }
            
            
            $oldValue = $newKey;
            $i = $nextValue + 1;
            if(($i + 1) == $total ){
                $percent = intval($i/$total * 100)."%";
                $timeRemaining = 0;
            } else {
                $percent = intval($i/$total * 100)."%";
                $timeRemaining = (($total - $displaycounter)/60);
            }
            usleep(30000);
            
        
        echo '<script language="javascript">
        document.getElementById("progress").innerHTML="<div style=\"width:'.$percent.';background-color:#ddd;\">&nbsp;</div>";
        document.getElementById("information").innerHTML="'.$displaycounter.' row(s) of '. $total . ' processed. About ' . round($timeRemaining, 2) . ' minutes remaining.";
       </script>';
            
        
    
    // This is for the buffer achieve the minimum size in order to flush data
        echo str_repeat(' ',1024*64);
        
            
            
        }
         foreach($jsons as $key => $value) {
           $epSync[$newKey][$key] = $value; 
        }
        
    }
    
    
      
    

    谢谢, 杰森

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-12
      • 1970-01-01
      • 2021-03-26
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多