curl php循环不输出,php-循环中的cURL请求有时根本不返回任何内容

问题:

我正在使用PHP,cURL和公共API来获取json字符串.

这些json字符串的格式如下(简化后,平均大小约为50-60 kB):

{

"data": {},

"previous": "url",

"next": "url"

}

尝试做的是通过检查“ next”属性来获取从第一个字符串开始的所有json字符串.因此,我有一个while循环,只要有一个“ next”属性,我就获取下一个URL.

问题有时是,循环随机地在结束之前停止,我无法弄清楚为什么经过多次测试.

我之所以说是随机的,是因为有时循环会持续到最后,并且不会发生任何问题.有时在N个循环后崩溃.

到目前为止,我无法提取任何信息来帮助我对其进行调试.

我正在使用PHP 7.3.0,并从CLI启动我的代码.

到目前为止我尝试过的是:

检查标题:

没有头返回.没事

使用curl_errno()和curl_error():

我在执行请求(curl_exec($ch))之后立即尝试了以下代码,但它从未触发.

if(curl_errno($ch)) {

echo 'curl error ' . curl_error($ch) . PHP_EOL;

echo 'response received from curl error :' . PHP_EOL;

var_dump($response); // the json string I should get from the server.

}

检查响应是否返回null:

if(is_null($response))

或者如果我的json字符串有错误:

if(!json_last_error() == JSON_ERROR_NONE)

尽管我认为它没有用,因为如果cURL响应为null或为空,它将永远无效.触发此代码时,json错误代码为3(JSON_ERROR_CTRL_CHAR)

有问题的代码:

function apiCall($url) {

...

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);

}

$inc = 0;

$url = 'https://api.example.com/' . $id;

$jsonString = apiCall($url);

if(!is_null($jsonString)) {

file_put_contents('pathToDirectory/' . $id + $inc, $jsonString);

$nextUrl = getNextUrl($jsonString);

while ($nextUrl) {

$jsonString = apiCall($url . '?page=' . $nextUrl);

if(!is_null($jsonString)) {

$inc++;

file_put_contents('pathToDirectory/' . $id + $inc, $jsonString);

$nextUrl = getNextUrl($jsonString);

}

}

}

我期望我的代码能做什么:

不要随意停止,或者至少给我一个明确的错误代码.

解决方法:

问题是您的API可能返回空响应,格式错误的JSON甚至状态码为200的错误,您将立即停止执行.

由于您不控制API响应,因此您知道它会随机失败,并且您无权访问API服务器日志(因为您没有,对吧?);您需要在消费者中建立某种弹性.

很简单的事情(您需要对其进行调整)可能是

function apiCall( $url, $attempts = 3 ) {

// ..., including setting "$headers"

$ch = curl_init();

curl_setopt( $ch, CURLOPT_URL, $url );

curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );

curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );

for ( $i = 0; $i < $attempts; $i ++ ) {

$response = curl_exec( $ch );

$curl_info = curl_getinfo( $ch );

if ( curl_errno( $ch ) ) {

// log your error & try again

continue;

}

// I'm only accepting 200 as a status code. Check with your API if there could be other posssible "good" responses

if ( $curl_info['http_code'] != 200 ) {

// log your error & try again

continue;

}

// everything seems fine, but the response is empty? not good.

if ( empty( $response ) ) {

// log your error & and try again

continue;

}

return $response;

}

return null;

}

这将使您可以执行以下操作(从代码中提取):

do {

$jsonString = apiCall($url . '?page=' . $nextUrl);

$nextUrl = false;

if(!is_null($jsonString)) {

$inc++;

file_put_contents('pathToDirectory/' . $id + $inc, $jsonString);

$nextUrl = getNextUrl($jsonString);

}

}

while ($nextUrl);

我没有检查API的返回是否为非空,不是连接错误,状态是否不同于’200’以及无效的JSON.

您可能还需要检查这些内容,具体取决于您使用的API的脆弱程度.

标签:error-handling,http,curl,json,php

来源: https://codeday.me/bug/20191108/2007001.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值