Created
January 27, 2013 02:22
-
-
Save mia-0032/4645883 to your computer and use it in GitHub Desktop.
simple_xml_loadを使ったXMLパーサー
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* simple_xml_loadを使ったXMLパーサー | |
*/ | |
class XmlLoader { | |
const DISPLAY_XML_ERROR_LIMIT = 3; //一箇所が不適切なXMLになっていると連鎖的にエラーが大量に出るので。 | |
/** | |
* XMLをパースする | |
* @param string XMLのURL | |
* @return SimpleXMLElement | |
*/ | |
public function load($url){ | |
$xml_text = $this->getXmlText($url); | |
//simple_load_xmlのエラーを抑制 | |
libxml_use_internal_errors(TRUE); | |
$feed_xml = simplexml_load_string($xml_text, null, LIBXML_NOCDATA); | |
$errors = libxml_get_errors(); | |
libxml_clear_errors(); | |
if ($errors) { //$errorsはLibXMLErrorクラスのインスタンスの配列。 | |
$error_msg = array(); | |
foreach ($errors as $key => $error) { | |
if($key >= self::DISPLAY_XML_ERROR_LIMIT){ | |
break; | |
} | |
//LibXMLErrorクラスについてはPHPのマニュアルの例にかいてあるエラー処理が便利。 | |
$error_msg[] = $this->formatXmlError($error, $xml_text); | |
} | |
throw new XmlLoaderException( | |
'XMLのパースでエラーが発生しました。詳細は以下の通りです。' . PHP_EOL . PHP_EOL . | |
implode(PHP_EOL . PHP_EOL, $error_msg) | |
); | |
} | |
return $feed_xml; | |
} | |
/** | |
* XMLファイルを取得 | |
* @param $url 取得するXMLのURL | |
* @return string 取得したXMLのテキスト | |
* @throws XmlLoaderException 取得に失敗した場合 | |
*/ | |
private function getXmlText($url){ | |
//Warning対策 | |
ob_start(); | |
$file_text = file_get_contents($url); | |
$warning = ob_get_contents(); | |
ob_end_clean(); | |
//Warningがあれば例外を投げる | |
if ($warning) { | |
throw new XmlLoaderException('エラーが発生しました:' . $warning); | |
} | |
if(empty($file_text)){ | |
throw new XmlLoaderException('取得したファイルが空です。'); | |
} | |
if(is_string($file_text) === FALSE){ | |
throw new XmlLoaderException('取得したファイルが文字列ではありません。'); | |
} | |
return $file_text; | |
} | |
/** | |
* LibXMLErrorを整形する。 | |
* @param LibXMLError $error エラー | |
* @param string $xml_text XMLのテキスト | |
* @return string エラー詳細 | |
* @see http://php.net/manual/ja/function.libxml-get-errors.php の例1 | |
*/ | |
private function formatXmlError(LibXMLError $error, $xml_text){ | |
$xml = explode(PHP_EOL, $xml_text); | |
$return = $xml[$error->line - 1] . PHP_EOL; | |
$return .= str_repeat('-', $error->column) . "^" . PHP_EOL; | |
switch ($error->level) { | |
case LIBXML_ERR_WARNING: | |
$return .= "Warning $error->code: "; | |
break; | |
case LIBXML_ERR_ERROR: | |
$return .= "Error $error->code: "; | |
break; | |
case LIBXML_ERR_FATAL: | |
$return .= "Fatal Error $error->code: "; | |
break; | |
} | |
$return .= trim($error->message) . PHP_EOL . | |
" Line: $error->line" . PHP_EOL . | |
" Column: $error->column"; | |
if ($error->file) { | |
$return .= PHP_EOL . " File: $error->file"; | |
} | |
return $return . PHP_EOL . PHP_EOL . "--------------------------------------------" . PHP_EOL . PHP_EOL; | |
} | |
} | |
class XmlLoaderException extends Exception{} | |
$feed_url = 'http://make-audio.blogspot.com/feeds/posts/default'; | |
try{ | |
$xml_loader = new XmlLoader; | |
$xml = $xml_loader->load($feed_url); | |
var_dump($xml); | |
}catch(Exception $e){ | |
header("HTTP/1.0 500 Internal Server Error"); | |
echo 'エラーが発生しました。<br>'; | |
echo 'メッセージ:' . $e->getMessage() . '<br>'; | |
echo '発生箇所:' . $e->getFile() . ' 行:' . $e->getLine() . '<br>'; | |
echo 'デバッグ:' . '<br>'; | |
echo $e->getTraceAsString() . '<br>'; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment