curl停止脚本执行

3

我的脚本使用curl通过smugsmug api将图像上传到smugsmug网站。我循环遍历一个文件夹并上传其中的每个图像,但在上传3-4个图像后,curl_exec会失败,停止一切并防止其他图像上传。

$upload_array = array(
    "method" => "smugmug.images.upload",
    "SessionID" => $session_id,
    "AlbumID" => $alb_id,
    "FileName" => zerofill($n, 3) . ".jpg",
    "Data" => base64_encode($data),
    "ByteCount" => strlen($data),
    "MD5Sum" => $data_md5);
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $upload_array);
curl_setopt(
    $ch, CURLOPT_URL, 
    "https://upload.smugmug.com/services/api/rest/1.2.2/");
$upload_result = curl_exec($ch); //fails here
curl_close($ch);

更新: 我在我的脚本中添加了日志记录。当它失败时,日志记录会在fwrite($fh, "begin curl\n");后停止。

fwrite($fh, "begin curl\n");
$upload_result = curl_exec($ch);
fwrite($fh, "curl executed\n");
fwrite($fh, "curl info: ".print_r(curl_getinfo($ch,true))."\n");
fwrite($fh, "xml dump: $upload_result \n");
fwrite($fh, "curl error: ".curl_error($ch)."\n");

i also

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60*60);

2
是否出现任何错误?也许你的脚本超过了时间限制。 - Neil Aitken
3
您是否开启了错误报告、错误显示或记录日志?您是否使用过 curl_getinfo() 和 curl_errmsg() 函数? - GZipp
6个回答

3

不确定问题出在哪里...当它失败时,响应中有什么?系统和Apache日志说了什么?

现在如果我是你,我就不会在循环中使用 curl_init()curl_close()。相反,在循环之前初始化,循环结束后关闭 - 然后在循环内部我会使用 curl_set_opt 来设置URL和不同的参数,并调用 curl_exec()。这可能是所有这些句柄超过某种系统限制或其他原因。如果您需要/想要使用多个连接,则可以使用 curl_multi 或编写一些管理函数/类来管理多个句柄。


我无法访问Apache日志,它突然停止了。 - Funky Dude
1
@prodigitalson - 我想你的意思是"...我不会在循环中使用curl_init()和curl_close()。" - GZipp
@Funky Dude:那么你需要暂时打开 display_errors,并查看是否可以从 curl 获取返回给你的响应内容。如果没有任何关于失败原因的信息,我们只能猜测。 - prodigitalson
@prodigitalson:错误显示和报告已开启。它会在curl_exec之前显示错误。在它失败的那一点上,curl_exec会停止一切而不显示任何内容。 - Funky Dude

1

1- 强制Curl向你展示更多关于它的操作信息

curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_HEADER, true);

2- 如果您不在安全模式下,请确保将以下代码放在脚本开头以显示 PHP 错误:

<?php
ini_set('display_errors', '1');
error_reporting(E_ALL);

3- 你也可以尝试在CLI模式下运行你的脚本。

4- 最后,如果你还没有进入安全模式,你可以尝试使用exec()直接运行curl二进制文件。

<?php

$curl_str = "curl -k -o /my/path/curl_output.log -d 'var1=".$value1."&var2=".$value2."& etc...' https://upload.smugmug.com/services/api/rest/1.2.2/";
$r = exec($curl_str);

Curl在Safari和Chrome浏览器中无法工作,$r=curl_exec($curl)的结果为false。它会挂起,但我使用curl_setopt($curl, CURLOPT_TIMEOUT, 5)停止了挂起。但是在命令行中运行php script.php时,它的结果为true。 - Timo

1
我们可能需要更多信息才能提供帮助,但听起来可能是一个超时问题。
打开错误报告或检查您的错误日志,看是否有任何异常情况。
尝试使用CURLOPT_TIMEOUT设置长的cURL超时时间。
还要检查您的脚本超时时间是否足够,并使用set_time_limit()进行增加。

0
我正在使用以下ajax来调用ajax.php文件中的一个函数。
$.ajax({
            url:'ajax.php?action=save_parcel',
            data: new FormData($(this)[0]),
            cache: false,
            contentType: false,
            processData: false,
            method: 'POST',
            type: 'POST',
            success:function(resp){
             if(resp){
             resp = JSON.parse(resp)
        
        if(resp == 1){
            //var nw = window.open('print_pdets.php? 
        ids='+resp.ids,"_blank","height=700,width=900")
            alert_toast('Data successfully saved',"success");
            setTimeout(function(){
              location.href = 'index.php?page=parcel_list';
            },2000)

        }
        }
            }
        })

以下是从上面调用的ajax.php -> action=save_parcel: ajax:
<?php
ob_start();
date_default_timezone_set("Africa/Nairobi");

$action = $_GET['action'];
include 'admin_class.php';
$crud = new Action();

if($action == 'save_parcel'){
    $save = $crud->save_parcel();
    if($save)
        echo $save;
}
ob_end_flush();
?>

然后从上面调用 admin.php(save_parcel) 函数:

function save_parcel(){   
extract($_POST);
        
                $login_name=$_SESSION['login_name'];
                $agent_id=$_SESSION['login_id'];
                $data .= ", reference_number='$ref' ";
                $data .= ", created_by='$login_name' ";
                $data .= ", agent_id='$agent_id' ";
                if($save[] = $this->db->query("INSERT INTO parcels set 
                  $data"))
                    $ids[]= $this->db->insert_id;
                $message ="Dear" ." ".$recipient_name.",". "Your parcel reference No:"." ".$ref. " "."has been sent from"." ".Branch_name." "."We will notify you when your parcel arrives in"." ".To_branch.". "."Thank you for using K-Prestige shuttle. You may reach us anytime on 0733xxx/0722XXXX";
                
                
            $url = "http://localhost:8130/api/1/webconnection/1";

            //Initiate cURL.
            $ch = curl_init($url);
            
            //The JSON data.
             $jsonData = array( 
                                    'secret' => '123', 
                                    'message' => $message, 
                                    'recipients' => array(array( 
                                            'type' => 'address', 
                                            'value' => '07358688'
                                    ))
                            );
                    
            //Encode the array into JSON.
            $jsonDataEncoded = json_encode($jsonData);
            

            //Tell cURL that we want to send a POST request.
            curl_setopt($ch, CURLOPT_POST, 1);

            //Attach our encoded JSON string to the POST fields.
            curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);

            //Set the content type to application/json
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: 
            application/json')); 

            //Execute the request
            $result = curl_exec($ch);
              if(curl_errno($ch))
                {
                    echo 'error:' . curl_error($ch);
                }

                curl_close($ch);
}

注:
上述是发送短信消息,它能够很好地完成,但应用程序光标保持不确定循环旋转,而不是像上面所示的跳转到location.href = 'index.php?page=parcel_list'。


0
你可以尝试直接输出curl_error()来查看是否起作用:
$upload_result = curl_exec($ch); //fails here

$error = curl_error($ch);    
if ($error) echo "CURL Error: $error";

curl_close($ch);

如果这并没有帮助,检查你的 phpinfo(); 来查看是否全局关闭了错误报告(查找 display_errors 设置)。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接