2015-04-27 3 views
0

У меня есть код php, который вызывает api, который у меня есть на другом сервере/экземпляре, и эхо-ответ. Всякий раз, когда я пытаюсь запустить php ниже в браузере, я получаю xml-синтаксический анализ с указанием extra content at the end of the document. Я не могу понять, где ошибка в моем коде, любые указатели были бы очень благодарны!Ошибка синтаксического анализа XML с PHP

PHP:

<?php 


//define API instance info 
define('API_URL','somewhere.com/getAllAlbums'); 
define('API_ID','someuser'); 
define('SIGNATURE','somekey'); 

// Generate a request date stamp 
$request_date=date("mdYHis"); 

// Get token - 
// load the existing token, and add 1 to it 
$fp=fopen("/somedirectory","r"); 
$token=fread($fp,filesize("/samedirectoryasabove")); 
fclose($fp); 
$token=sprintf("%d",$token); 
$token++; 

// Write out the new token in place of the old one for next time 
$fp=fopen("/samedirectoryasabove","w"); 
$written=fwrite($fp,$token); 
fclose($fp); 

// Generate the hash to be sent and matched 
$auth_string=API_ID . ":" . $token . ":" . $request_date; 
$auth_string_hash=base64_encode(hash_hmac('sha256',$auth_string,SIGNATURE,1)); 

// Set up the POST request for information 
// This could be different for each different API information request 
$post_fields=array('token'=>$token,timestamp=>$request_date); 
$post_string=""; 
foreach($post_fields as $key=>$value) 
     $post_string.=$key . "=" . $value . "&"; 
$post_string=rtrim($post_string,"&"); 

// Use CURL to make the request to the API server 
$request = API_URL; 
$curl = curl_init($request); 
curl_setopt($curl,CURLOPT_POST, count($post_fields)); 
curl_setopt($curl,CURLOPT_POSTFIELDS, $post_string); 
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: ' . $auth_string_hash)); 
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); 
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); 
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); 
$response=curl_exec($curl); 
curl_close($curl); 

// Echos response, problem here? 
header('Content-Type: text/xml'); 
echo "$response"; 

?> 

API PHP

<?php 

error_reporting(E_ALL^E_NOTICE); 

// The following four statements allow AJAX style Javascript requests to get through by allowing certain headers 
header('Access-Control-Allow-Origin: *'); 
header('Access-Control-Allow-Methods: OPTIONS, HEAD, GET, POST'); 
header('Access-Control-Max-Age: 604800'); 
header('Access-Control-Allow-Headers: X-Requested-With,Content-Type, Content-Length, Authorization, Connection'); 


$valid_user = 'someuser'; 

//db host 
define(DB_HOST,'192.168.1.116'); 
define(DB_USER,'DBUSER'); 
define(DB_PASSWORD,'DBPASS'); 
define(DB_DATABASE,'databasename'); 
$dbConn=mysqli_connect(DB_HOST,DB_USER,DB_PASSWORD,DB_DATABASE); 

$query="select signature from api_keys where id='$valid_user'"; 
$result=mysqli_query($dbConn,$query); 
$cnt=mysqli_num_rows($result); 
if($cnt!=1) 
     invalidRequest('001'); 

$row=mysqli_fetch_assoc($result); 
$signature = $row["signature"]; 



$headers=apache_request_headers(); 
$digest=$headers["Authorization"]; 


if (is_null($digest)) 
{ 
     invalidRequest('002'); 
} 

// Attempt to auth the request - grab the token and request date provided by the external API caller 
$token=$_POST["token"]; 
$request_date=$_POST["timestamp"]; 

// No token or reqauest generates an error 
if(!$token || !$request_date) 
{ 
     invalidRequest('002'); 
} 
// The page wasn't called right, so throw an error 
if(!$_GET["action"]) 
{ 
    invalidRequest('002'); 
} 



$hash_string=base64_encode(hash_hmac('sha256',$valid_user . ":" . $token . ":" . $request_date,$signature,1)); 
//echo $hash_string . ":" . $digest; 
//exit(); 
// Compare the hash we generated with the one provided by the requester 
// If they do not match, throw an error 
if($hash_string!=$digest) 
{ 
     invalidRequest('002'); 
} 


$query="select token from api_tokens where id='$valid_user' and token='$token'"; 
$result=mysqli_query($dbConn,$query); 
$cnt=mysqli_num_rows($result); 
('$valid_user','$token','" . date("Y-m-d H:i:s") . "')"; 

// Get the information requested and return it as XML string. 
if($_GET["action"]=='getAllAlbums') 
{ 
    // This is a request for all the albums in the DB 
    $query="select id,artist,name from albums order by id"; 
    $result=mysqli_query($dbConn,$query); 
    if(mysqli_num_rows($result) < 1) 
     invalidRequest('006'); 
    $xml_string="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
    $xml_string.="<music_inventory>\n"; 
    while($row=mysqli_fetch_assoc($result)) 
    { 
     $xml_string.="<album id=\"" . $row["id"] . "\">\n"; 
     $xml_string.="<artist>" . htmlentities($row["artist"]) . "</artist>\n"; 
     $xml_string.="<name>" . htmlentities($row["name"]) . "</name>\n"; 
     $xml_string.="</album>\n"; 
    } 
    $xml_string.="</music_inventory>"; 
} 
else if($_GET["action"]=='getAlbum') 
{ 
    // This was a request for a single album's full info 
    $query="select id,type,albumart,artist,name,year,label,disc,totaldiscs from albums where id='" . $_POST["albumID"] . "'"; 
    $result=mysqli_query($dbConn,$query); 
    if(mysqli_num_rows($result) < 1) 
     invalidRequest('006'); 
    $xml_string="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
    $xml_string.="<music_inventory>\n"; 
    while($row=mysqli_fetch_assoc($result)) 
    { 
     if($row["type"]=='F') 
      $type='full length'; 
     else if($row["type"]=='E') 
      $type='EP'; 
     else 
      $type='unknown'; 
     $xml_string.="<album id=\"" . $row["id"] . "\" type=\"$type\" albumart=\"" . $row["albumart"] . "\">\n"; 
     $xml_string.="<artist>" . $row["artist"] . "</artist>\n"; 
     $xml_string.="<name>" . $row["name"] . "</name>\n"; 
     $xml_string.="<year>" . $row["year"] . "</year>\n"; 
     $xml_string.="<label>" . $row["label"] . "</label>\n"; 
     $xml_string.="<disc>" . $row["disc"] . "</disc>\n"; 
     $xml_string.="<totaldiscs>" . $row["totaldiscs"] . "</totaldiscs>\n"; 
    } 
    $query="select id,track_number,track_title,track_artist from tracklist where id='" . $_POST["albumID"] . "' order by track_number"; 
    $result=mysqli_query($dbConn,$query); 
    $xml_string.=" <tracklist>\n"; 
    while($row=mysqli_fetch_assoc($result)) 
    { 
     $xml_string.="<track id=\"" . $row["track_number"] . "\">" . htmlentities($row["track_title"]) . "</track>\n"; 
    } 
    $xml_string.="</tracklist>\n"; 
    $xml_string.="</album>\n"; 
    $xml_string.="</music_inventory>\n"; 
} 
else if($_GET["action"]=='getTrackList') 
{ 
    // This was a request for a specific album's track list 
    $xml_string="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
    $query="select id,track_number,track_title,track_artist from tracklist where id='" . $_POST["albumID"] . "' order by track_number"; 
    $result=mysqli_query($dbConn,$query); 
    $xml_string.="<music_inventory>"; 
    $xml_string.="<album id=\"" . $_POST["albumID"] . "\"></album>\n"; 
    $xml_string.="<tracklist>\n"; 
    while($row=mysqli_fetch_assoc($result)) 
    { 
     $xml_string.="<track id=\"" . $row["track_number"] . "\">" . $row["track_title"] . "</track>\n"; 
    } 
    $xml_string.="</tracklist>\n"; 
    $xml_string.="</music_inventory>"; 
} 
else 
{ 
    // This did not have a valid request attached to it 
    invalidRequest('003'); 
} 
// Echo out the result as XML 
header('Content-Type: text/xml'); 
echo $xml_string; 
exit(); 

function invalidRequest($error) 
{ 
    // This is the error thrown in all cases above. 
    $xml_string="<?xml version=\"1.0\"?>\n"; 
    $xml_string.="<systemerror>\n"; 
    $xml_string.=" <errorcode>$error</errorcode>\n"; 
    $xml_string.="</systemerror>\n"; 
    header('Content-Type: text/xml'); 
    echo $xml_string; 
     exit(); 
} 

?> 
+0

Вы создаете XML «вручную» (конкатенация строк). Это, как известно, процедура, подверженная ошибкам. Это также известная процедура, сделанная неопытными программистами. Оба в сочетании это более или менее часто приводит к ситуациям с ошибками, подобным тем, которые вы описываете (* «дополнительный контент в конце документа» *). Пожалуйста, обращайтесь к существующим материалам Q & A, которые мы имеем на сайте об этой ошибке. Может быть много конкретных причин, почему это точно вызывает ошибку * в вашей ситуации *, но Q & A мудрый целью является описать сообщение об ошибке и предложить общие решения для него. – hakre

ответ

0

Это сообщение об ошибке означает, что XML-строка, вы выводите недействителен. Там (возможно) ничего плохого в PHP код вы опубликовали. Взгляните на источник и убедитесь, что каждый элемент правильно закрыт и правильно вложен. Возможно, API отправляет вам плохие данные. Если ответ API всегда имеет ту же ошибку, вы можете взломать исправление, выполнив операцию строки (str_replace или preg_replace, например), прежде чем передавать ее в ваш браузер или simplexml_decode_string().