2017-09-14 47 views
0

我的API有两种可能的响应。我需要从收到的文本响应中获取数据,并需要将它们存储为变量。如何从PHP中的两个可能的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调用第一次可能的反应,我总是在最后一行中的错误(回声......),如下图所示:

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

但是,没有问题,当我收到的第2个反应。它显示了,因为我想:

状态是请求错误,我的参考编号是501

请帮帮忙!

+2

为什么不让API响应变成更好的格式,比如json?即使XML会更好。似乎很奇怪有一个需要手动解析的自定义响应。 –

+0

'$ rStatus' ='请求接受你的',所以它不匹配。我同意Magnus Eriksson的观点,从您的API中创建更加健全的响应。 – aynber

+0

...更糟糕......您实际上有两种不同的格式和自定义格式,具体取决于请求是否被接受。 –

回答

3

这不是最有效的方法,尝试使用一些适当的格式,如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); 
} 
+0

谢谢,但preg_match比strstr更快 – tsv

+1

@tsv不是说这不是真的,但是你有没有适合这种情况的声明的任何参考? –

+1

@tsv这可能是,但检查此https://stackoverflow.com/a/6433513/2394254 – mega6382

0

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

$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]之前;
相关问题