Skip to content

Instantly share code, notes, and snippets.

@mia-0032
Created January 27, 2013 02:22
Show Gist options
  • Save mia-0032/4645883 to your computer and use it in GitHub Desktop.
Save mia-0032/4645883 to your computer and use it in GitHub Desktop.
simple_xml_loadを使ったXMLパーサー
<?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