【问题标题】:How to grab data from one response from two possible API text responses in PHP?如何从 PHP 中两个可能的 API 文本响应中的一个响应中获取数据?
【发布时间】:2017-09-14 23:58:41
【问题描述】:

我的 API 有两种可能的响应。我需要从收到的文本响应中获取数据并将它们存储为变量。

API 调用:

  $url="http://91.101.61.111:99/SendRequest/?mobile=9999999999&id=11011&reqref=501";
  $request_timeout = 60;
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_TIMEOUT, $request_timeout);
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $request_timeout);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  $output = curl_exec($ch);
  $curl_error = curl_errno($ch);
  curl_close($ch); 

可能的纯文本 API 响应:

REQUEST ACCEPTED your ref=<myref> system_reference=<sysref>
Or,
REQUEST ERROR errorno=<error>;your ref=<myref>;system_reason=<sysreason>

如果出现第一个可能的响应,我需要获取如下数据:

$status = "REQUEST ACCEPTED";  
$myref = "501";  
$sysref = "BA01562";  

如果出现第二种可能的响应,我需要获取如下数据:

$status = "REQUEST ERROR";
$error = "25";
$myref = "501";
$sysreason = "Duplicate request";  

我试过了:

$response = preg_match('/([\w\s]+) ([\w]+)/', $output, $res);
$rstatus = $res[1];

if ($rstatus == "REQUEST ACCEPTED")
{
    $raccepted = preg_match('/([\w\s]+) your ref=([\d]+) system_reference=([\w]+)/', $output, $matches);
    $status = $matches[1];  
    $myref = $matches[2];  
    $sysref = $matches[3];  
}
elseif ($rstatus == "REQUEST ERROR")
{
    $rerror = preg_match('/([\w\s]+) errorno=([\d]+);your ref=([\d]+);system_reason=([\w\s]+)/', $output, $matches);
    $status = $matches[1];
    $error = $matches[2]; 
    $myref = $matches[3];  
    $sysreason = $matches[4];  
}

echo "Status is $status, My Ref ID is $myref";

现在,当我从 API 调用中获得第一个可能的响应时,我总是在最后一行(回显 ....)上得到错误,如下所示:

( ! ) 注意:未定义变量:status
( ! ) 注意:未定义变量:myref
状态是,我的参考 ID 是

但是当我收到第二个回复时没有问题。它显示为我想要的:

状态为 REQUEST ERROR,我的 Ref ID 为 501

请帮忙!

【问题讨论】:

  • 为什么不把 API 响应做成更好的格式,比如 json?甚至 XML 会更好。有一个需要手动解析的自定义响应似乎很奇怪。
  • $rStatus = REQUEST ACCEPTED your,所以它不会匹配。我同意 Magnus Eriksson 的观点,从你的 API 中创建一个更理智的响应。
  • ...更糟糕的是...您实际上有 两种不同的和自定义格式,具体取决于请求是否被接受。

标签: php preg-match preg-split


【解决方案1】:

这不是最有效的方法,请尝试使用一些正确的格式,例如JSON 或其他东西。无论如何,这是一个解决方案:

$success = stristr($output, "REQUEST ACCEPTED");

if($success)
{
    $data = stristr($output, "ref");
    $raccepted = preg_match('/ref=([\d]+) system_reference=([\w]+)/', $data, $matches);
    var_dump($matches);
}
else
{
    $data = stristr($output, "errorno");
    $rerror = preg_match('/errorno=([\d]+);your ref=([\d]+);system_reason=([\w\s]+)/', $data, $matches);
    var_dump($matches);
}

【讨论】:

  • 谢谢,但是 preg_match 比 strstr 快
  • @tsv 不是说这不是真的,但是你有什么适合这种情况的陈述的参考吗?
  • 这个答案也更具可读性,并将为 OP 提供响应中的所有不同值。
  • preg_match 与 strstr 执行时间 preg 匹配:0.0034110546112061 总执行时间 strstr:0.00382399559021。我试了很多次,结果都一样
  • @tsv: “preg_match 比 [a]n strstr 更快”:不,这是错误的。
【解决方案2】:

你应该改变你的正则表达式

$response = preg_match('/([\w\s]+) ([\w]+)/', $output, $res); 

$response = preg_match('/\w+ \w+/is', $output, $res);

测试:

php > preg_match('/\w+ \w+/is', "REQUEST ACCEPTED your ref=some system_reference=some123", $res);
php > var_dump($res);
php shell code:1:
array(1) {
  [0] =>
  string(16) "REQUEST ACCEPTED"
}
php > preg_match('/\w+ \w+/is', "REQUEST ERROR errorno=123;your ref=SOMEref;system_reason=reason", $res);
php > var_dump($res);
php shell code:1:
array(1) {
  [0] =>
  string(13) "REQUEST ERROR"
}

其他建议:

  1. 使用 ^ 和 $(常规部分的开头和结尾)在测试常规之前修剪您的响应。
  2. 在这种情况下使用 === 而不是 ==
  3. 检查是否存在 $res[1];之前 $rstatus = $res[1];

【讨论】:

    猜你喜欢
    • 2018-11-20
    • 2020-03-14
    • 2019-12-16
    • 2014-06-15
    • 2019-09-04
    • 2021-01-31
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    相关资源
    最近更新 更多