2013-10-22 14 views
0

我一直在獲取由此函數檢索的名稱的UTF8版本,但由於某些原因,它不會以正確的字母輸出它。PHP SimpleXML - 無法正確地將SteamID64轉換爲帶有UTF8的Steam名稱

輸出示例:

ѕqÃ…ιÑÂтâ„Â「ÑÂ」 

預期輸出:

ѕqυιятℓє 

我在文件上跑的字符集檢查,該字符串作爲其正在從的file_get_contents和拉動函數的輸出以及源XML文件。 MySQL也沒有得到正確的版本。

此外,SimpleXML確實支持UTF-8。

須藤文件-i DEBUG.TXT

debug.txt: txt/plain; charset=utf-8 

MySQL的整理

utf8_general_ci 

源XML文件頭

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 

這(在代碼中兩次) -

$enc = mb_detect_encoding($xml, 'UTF-8', true); 
    echo 'Detected encoding '.$enc; 

輸出:

Detected encoding UTF-8 
Detected encoding UTF-8 

我不知道還有什麼地方檢查UTF-8字符集,或者說是我我需要做的第一個地方。我希望這裏有人會知道如何獲得預期的名稱版本。提前致謝。

文本文件(日誌)輸出功能:

function log_output($message){ 
    $file = 'debug.txt'; 
    $current = file_get_contents($file); 
    $current .= $message."\n"; 
    file_put_contents($file, $current); 
} 

源代碼:

// Converts SteamID(64) to the users current name on Steam. 
     function steamid64_to_name($steamid64) { 
      // Get User Profile Data 
      $xml = file_get_contents('http://steamcommunity.com/profiles/'.$steamid64.'/?xml=1'); 
      $enc = mb_detect_encoding($xml, 'UTF-8', true); 
      echo 'Detected encoding '.$enc; 
      $xml = simplexml_load_string($xml, null, LIBXML_NOCDATA); 
      if(!empty($xml)) { 
      if(isset($xml->steamID)) { 
       $username = $xml->steamID;// Example: steamcommunity.com/profiles/76561198077095013/?xml=1 
      } else { 
       $username = "Username Not Found"; 
      } 
      } else { 
      $username = "User XML Not Found"; // Example: steamcommunity.com/profiles/0/?xml=1 
      } 
      $enc = mb_detect_encoding($xml, 'UTF-8', true); 
      echo 'Detected encoding '.$enc; 
      return $username; 
     } 
+0

你如何輸出這個用戶名? –

+0

更新了OP以顯示MySQL排序規則和將其輸出到允許我閱讀的文件的功能。 – Caffeine

+0

您是否正在使用知道它是UTF-8文件的編輯器查看日誌文件? –

回答

0

什麼你問的是少談SimpleXML的,但更與你的輸出編碼。輸出編碼是您發送給瀏覽器的數據以及與該數據一起使用的編碼信息(data + meta)。

您還commmented,即使用Apache HTTPDs':

AddDefaultCharset utf-8 

固定的問題給你。那就是告訴瀏覽器你要發送給它的數據是UTF-8編碼的。以前,你告訴瀏覽器它會是一些拉丁語 - ñ東西,因此你有這些錯誤的外觀字符。只要考慮到你需要在該字母旁邊指定語言,以便接收該語言的人能夠理解要用哪種語言閱讀該字母。

除此之外,還有你應該考慮到發現問題快,並且不寫太多代碼大拇指的一些通用規則:如果你讀了從SimpleXMLElement一個字符串,它會給你

  • 數據UTF-8編碼。不管你創建它的原始文件的編碼是什麼。
  • SimpleXML處理大部分自己的重新編碼,你需要的只是一個正常的iconv安裝,通常情況下(否則推薦)。
  • 對自己嚴格要求,千萬不要猜測像你這樣用mb_detect_encoding做的編碼。這在技術上是不可能的,相反 - 如果它的編碼是未知的 - 從數據源獲取這些信息,而不是從數據中獲取(技術上不可能從數據中獲得它,這總是一個猜測)。
  • 最後但並非最不重要,因爲這關於遠程服務,你應該總是在這裏添加一個間接層。你想在這裏介紹的最不重要的事情就是緩存遠程請求,因此將它包裝到一個類中是第一步。

的一些示例爲您的蒸汽API acccess:

<?php 
/** 
* PHP SimpleXML - Unable to correctly convert SteamID64 to Steam 
* Name with UTF8 
* 
* @link http://stackoverflow.com/q/19507614/367456 
*/ 

$profile = new SteamProfile('76561198027590831'); 
echo $profile->getUsername(), "\n"; 
var_dump((string)$profile); 

/** 
* Class SteamProfile 
* 
* Converts SteamID(64) to the users current name on Steam. 
*/ 
class SteamProfile 
{ 
    const STEAMAPI_URL_MASK = 'http://steamcommunity.com/profiles/%s/?xml=1'; 
    const UNKONWN_NAME_MASK = 'User #%s (Username Not Found)'; 

    private $steamId; 
    private $xml; 

    public function __construct($steamId) 
    { 
     $this->steamId = $steamId; 
    } 

    public function getUsername() 
    { 
     $xml = $this->getXml($this->steamId); 

     return $xml->steamID 
      ? (string)$xml->steamID 
      : sprintf(self::UNKONWN_NAME_MASK, $this->steamId) 
      ; 
    } 

    private function getXml($steamId) 
    { 
     if ($this->xml) { 
      return $this->xml; 
     } 

     $url = sprintf(self::STEAMAPI_URL_MASK, $steamId); 

     if (!$xml = simplexml_load_file($url)) { 
      throw new UnexpectedValueException(sprintf('Unable to load XML from "%s"', $url)); 
     } 

     return $this->xml = $xml; 
    } 

    public function __toString() 
    { 
     return sprintf("%s (SteamID: %s)", $this->getUsername(), $this->steamId); 
    } 
} 

示例性輸出(UTF-8編碼):

ѕqυιятℓє | [A] 
string(51) "ѕqυιятℓє | [A] (SteamID: 76561198027590831)" 

作爲示例,並且輸出顯示中,沒有需要關心儘管Steam提供了有效的XML,而Simplexml僅用於有效的XML,但編碼過多。在您的網站上使用UTF-8編碼爲您需要先將UTF-8中的數據重新編碼爲您的目標編碼。

也通過使用SteamProfile對象,您可以稍後用不同的實現替換它。例如。有一個可以將遠程請求委託給不同的層。