Извлечение JSON из результатов cURL

#php #regex #json #curl #preg-replace

#php #регулярное выражение #json #curl #preg-заменить

Вопрос:

Я новичок в регулярных выражениях и пытаюсь получить ответ JSON из запроса cURL в PHP.

Я думал об использовании preg_match_all.

Редактировать: следовало бы упомянуть, что полный ответ от curl_exec () включает информацию заголовка, поэтому мне нужно извлечь JSON.

 HTTP/1.1 401 Unauthorized Server: Apache-Coyote/1.1 WWW-Authenticate:  Digest realm="",  qop="auth", [... etc]
  

Нужный мне JSON выглядит примерно так (после всех заголовков):

 {  "requests" :  
  [ { 
     "request_id" : 10298, 
     "name" : "CURL Test2",  
     "submitter" : "First Last",  
     "hide" : false,  
     "priority" : 10,  
     "tags" : [ "label 2" ],  
     "body" : 
          { "type" : "html", "content" : "" },  
     "runs" : 0  
   } ] 
  }
  

Надеялся просто захватить все между фигурными скобками. Однако, когда я делаю это, он захватывает все, начиная с первой открывающей фигурной скобки и заканчивая первой закрывающей фигурной скобкой. Для расширения я просто хочу захватить все внутри, включая первую открывающую фигурную скобку и последнюю закрывающую фигурную скобку.

Технически это могло бы просто начинаться с первой открывающей фигурной скобки и возвращать все до конца ответа (после JSON ничего не следует).

Мысли?

Ответ №1:

Регулярное выражение — это здорово, но определенно не подходящий инструмент для этого.

Существует функция json_decode() , которая может справиться с этим за вас.

Это вернет структуру в виде объекта. Вы можете вернуть его в виде массива, установив для второго аргумента значение TRUE . Даже если в PHP нет этой функции, вам лучше написать или использовать существующий анализатор JSON, чем пытаться извлекать части с помощью регулярных выражений.

Если вы используете заголовки и вам нужно выделить тело в отдельную переменную, вам следует сделать что-то вроде следующего, где $ch это экземпляр curl и $result это возврат curl_exec() .

 $headerLen = curl_getinfo($ch, CURLINFO_HEADER_SIZE); 
$curlBody = substr($result, $headerLen);`
  

Комментарии:

1. Полный ответ от curl_exec() включает HTTP-заголовки и т.д. Может ли json_decode () справиться с этим?

2. @djreed Нет, но вы можете отключить вывод заголовков и возвращать только тело ответа, не так ли? В качестве альтернативы вы могли бы сделать $json = trim(strstr($response, "n")) .

3. Не уверен, как вернуть только тело ответа из curl_exec(). Обрезка строки не работает.

4. @djreed Между заголовками и телом должно быть n , поэтому код в комментарии должен работать. Или просто установите CURLOPT_HEADER для параметра значение false.

5. Только что понял, что это должно быть разделение на "nn" , а не только на одно, которое произойдет после первого заголовка 🙂

Ответ №2:

поскольку это помогло мне приблизиться к результату, но только «near» хочу поделиться своим результатом..

 $json = array ( "firstname" => "john" , "lastname" => "Doe") ; 
$jsonheader = array ( "Accept: application/json" 
, "Content-type:application/json" 
, "Authorization: OAuth oauth_token=xxxxx" ) ;

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://myurl.com?oAuth=12341231234' ); // set the target url
curl_setopt($ch, CURLOPT_POST, 1 ); // howmany parameter to post
curl_setopt($ch, CURLOPT_POSTFIELDS, $json ); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true ); // don't give anything back 
curl_setopt($ch, CURLOPT_HEADER, TRUE );  // need this to evaluate the response .. 
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $jsonheader ); // it is httpheader not httpheader"s" 

$result = curl_exec ($ch);

curl_close ($ch);
$resultarr = explode ( "n" , $result ) ;
$httpval = explode ( " " , $resultarr[0] ) ; // explode the first line

for ( $i=1 ;  $i < count( $resultarr) ; $i   ) {
    if ( is_array (json_decode( $resultarr[$i] , true)) ){
        $resultvals  = json_decode( $resultarr[$i] , true) ;
    }       
}
if ( $resultvals['YourKey'] <> '' ) {  // any accepted value in the response ... 
    if ( $httpval[1] == "201" )  {
        $error = 0 ; //  no error Overwrite error 2 
    } else {
        $error = 1 ;  // http response was not 201  .. 
    }
} else {
   $error = 2 ;  // any other error like "no response" or "other error"   
 }
  

Комментарии:

1. Объясните, что вы подразумеваете под «только рядом» — таким образом, читающие люди смогут понять, чего может не хватать / что необходимо.