Èñïîëüçîâàíèå XML â PHP
Äîñòàâêà öâåòîâ â Èçáåðáàø Ñëóæáà äîñòàâêè ñðåäè öâåòîâ.
Ýòà ñòàòüÿ, êàê Âû óæå ñêîðåå âñåãî ïîíÿëè èç íàçâàíèÿ, ïîñâÿùåíà
òîìó, êàê ìîæíî èñïîëüçîâàòü XML äëÿ õðàíåíèÿ äàííûõ, êîòîðûå áóäóò
èñïîëüçîâàòüñÿ èç ñêðèïòîâ, íàïèñàííûõ íà PHP. Áåäåì ñ÷èòàòü, ÷òî Âû óæå çíàåòå,
÷òî òàêîå XML è ñ ÷åì åãî åäÿò. Ïðèìåðû ê ñòàòüå Âû ìîæåòå ñêà÷àòü îòñþäà. Íàø
ïëàí òàêîé. Ñíà÷àëà ìû óçíàåì, êàêèå ôóíêöèè åñòü äëÿ ðàáîòû ñ XML â PHP è êàê
èìè ïîëüçîâàòüñÿ. ×òîáû ýòî ëó÷øå ïîíÿòü, ìû ðàññìîòðèì íåáîëüøîé ñêðèïò,
êîòîðûé áóäåò îòîáðàæàòü ñòðóêòóðó íàøåãî XML-äîêóìåíòà.
Ïðèñòóïèì. Íå õî÷ó ÿ íóäíî è äîëãî ðàññêàçûâàòü îáùèå ñëîâà ïðî òî, êàê ðàáîòàòü
ñ XML â PHP, ëó÷øå äàâàéòå ðàçáåðåì ýòî âñå íà ïðèìåðå. Èòàê, ïîñòàíîâêà çàäà÷è:
íàïèñàòü ñêðèïò, êîòîðûé áóäåò ïîêàçûâàòü ñòðóêòóðó XML-äîêóìåíòà. Â ïðèìåðàõ
ýòî ôàéë xml.php.
Ñíà÷àëà ñîçäàäèì XML-äîêóìåíò (â ïðèìåðàõ ýòî test.xml). Ïóñòü â ýòîì ôàéëå
áóäóò îïèñûâàòüñÿ ôîòîãðàôèè. Îñîáî ìóäðèòü ìû íå áóäåì, è îáîéäåìñÿ áåç
îïèñàíèÿ DTD (íå ïóòàòü ñ DDT :)). Çäåñü ïîÿâëÿåòñÿ ïåðâàÿ íåïðèÿòíàÿ
îñîáåííîñòü PHP: XML-äîêóìåíòû, êîòîðûå äîëæíû îáðàáàòûâàòüñÿ èç ñêðèïòà ìîãóò
áóòü íàïèñàíû â ñëåäóþùèõ êîäèðîâêàõ: US-ASCII, ISO-8859-1 è UTF-8. Ò.ê. íàì
íóæíî îïèñûâàòü ôîòîãðàôèè ïî-ðóññêè, òî ïðèäåòñÿ âûáðàòü ïîñëåäíþþ êîäèðîâêó,
ò.ê. â ïåðâûõ äðóõ íåò ðóññêèõ áóêâ. Íå âñå òåêñòîâûå ðåäàêòîðû ìîãóò ðàáîòàòü ñ
ýòîé êîäèðîâêîé. ß, íàïðèìåð, íàáèðàë XML â ðåäàêòîðå SciTE. Îí ìàëåíüêèé,
áåñïëàòíûé è ó íåãî õîðîøàÿ ïîäñâåòêà ñèíòàêñèñà (â òîì ÷èñëå PHP è XML). Íàø
XML-äîêóìåíò áóäåò âûãëÿäåòü òàê:
<?xml version="1.0" encoding="UTF-8"?>
<album>
<foto smallfoto="Fotos/1smallvelo.jpg " bigfoto="Fotos/1bigvelo.jpg ">
<title>Íàçâàíèå 1</title>
<comment>Äëèííûé êîììåíòàðèé
íà íåñêîëüêî ñòðîê 1</comment>
<date>26.05.2003</date>
<color/>
<detailed>0</detailed>
</foto>
<foto smallfoto="Fotos/smallbardak.jpg " bigfoto="Fotos/bigbardak.jpg ">
<title>Íàçâàíèå 2</title>
<comment> Äëèííûé êîììåíòàðèé
íà íåñêîëüêî ñòðîê 2</comment>
<date>27.05.2003</date>
<color/>
<detailed>1</detailed>
</foto>
</album>
"Ôèçè÷åñêèé" ñìûñë òåãîâ â XML ñåé÷àñ çíà÷åíèÿ íå èìååò (õîòÿ òàì âðîäå è òàê
âñå ïîíÿòíî). Åäèíñòâåííîå, ÷òî òîëüêî <color/> çäåñü ìîæåò îáîçíà÷àòü öâåòíàÿ
ôîòêà èëè íåò. Ýòî çäåñü òîëüêî äëÿ ïðèìåðà òåãà, ó êîòîðîãî íåò çàêðûâàþùåãîñÿ.
À òåïåðü íàïèøåì ñêðèïò, êîòîðûé ïîêàçûâàë áû ñòðóêòóðó XML-äîêóìåíòà. Äëÿ
ðàáîòû ñ XML â PHP åñòü áîëüøå 20 ôóíêöèé. Ðàññìîòðèì äëÿ íà÷àëà ñàìûå
íåîáõîäèìûå. Âîò ýòîò ñêðèïò:
<?
$xmlfilename = "test.xml";
$code = "UTF-8"; // Êîäèðîâêà xml-à
$curcode = "Windows-1251"; // Òåêóùàÿ êîäèðîâêà
$level = 0; // Óðîâåíü âëîæåííîñòè
$list = array(); // Ñïèñîê ýëåìåíòîâ â xml-ôàéëå
// Ïðåîáðàçóåò ñòðîêó èç Unicode
function encoding ($str)
{
global $code;
global $curcode;
$str = mb_convert_encoding($str, $curcode, $code);
return $str;
}
function drawspace()
{
global $level;
for ($i = 0; $i < $level * 10; $i++)
{
echo " ";
}
}
// Îáðàáàòûâàåò òåêñò ìåæäó òåãàìè
function characterhandler ($parser, $data)
{
global $code;
global $curcode;
drawspace();
$data = encoding($data, $curcode, $code);
$data = trim($data)."<br>";
echo $data;
}
// Îáðàáàòûâàåò îòêðûâàþùèåñÿ òåãè
function starthandler ($parser, $name, $attribs)
{
global $level;
global $list;
global $code;
global $curcode;
$name = encoding($name, $curcode, $code);
$list[] = $name;
drawspace();
echo "<<font color='blue' size='+1'>$name</font>";
foreach ($attribs as $atname => $val)
{
echo encoding("$atname => $val");
}
echo "><br>";
$level++;
}
// Îáðàáàòûâàåò çàêðûâàþùèåñÿ òåãè
function endhandler ($parser, $name)
{
global $level;
global $list;
array_pop($list);
$level--;
drawspace();
echo "<<font color='blue' size='+1'>/$name</font>><p>";
}
// Ñîçäàäèì ïàðñåð
$parser = xml_parser_create($code);
if (!$parser)
{
exit ("Íå ìîãó ñîçäàòü ïàðñåð");
}
else
{
echo "Ïàðñåð óñïåøíî ñîçäàí<p>";
}
// Óñòàíîâèì îáðàáîò÷èêè òåãîâ è òåêñòà ìåæäó íèìè
xml_set_element_handler($parser, 'starthandler', 'endhandler');
xml_set_character_data_handler($parser, 'characterhandler');
// Îòêðîåì ôàéë ñ xml
$fp = fopen ($xmlfilename, "r");
if (!$fp)
{
xml_parser_free($parser);
exit("Íå ìîãó îòêðûòü ôàéë");
}
while ($data = fread($fp, 4096))
{
if (!xml_parse($parser, $data, feof($fp)))
{
die(sprintf("Îøèáî÷êà âûøëà: %s â ñòðîêå %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
}
}
fclose ($fp);
xml_parser_free($parser);
?>
Ïîñëå îáúÿâëåíèé âñïîìîãàòåëüíûõ ôóíêöèé, íåîáõîäèìî â ïåðâóþ î÷åðåäü ñîçäàòü
ïàðñåð. Ýòî ìîæíî ñäåëàòü îäíîé èç ôóíêöèèé xml_parser_create èëè
xml_parser_create_ns. Ïåðâàÿ èìååò îäèí íåîáÿçàòåëüíûé ïàðàìåòð, êîòîðûé
îáîçíà÷àåò êîäèðîâêó, â êîòîðîé íàïèñàí XML-äîêóìåíò. Åñëè åãî íå óêàçàòü, òî
ïî-óìîë÷àíèþ ñ÷èòàåòñÿ, ÷òî îí íàïèñàí êàê ISO-8859-1. Íî, êàê ÿ ïèñàë âûøå, ýòî
íàì íå ïîäõîäèò è ìû âûáèðàåò UTF-8. Ò.ê. îáîçíà÷åíèå ýòîé êîäèðîâêè íàì åùå
ïîíàäîáèòñÿ, òî âûíåñåì åå â ãëîáàëüíóþ ïåðåìåííóþ ($code = "UTF-8";). Òàêæå
âûíåñåì òóäà êîäèðîâêó, â êîòîðîé áóäåò âûâîäèòüñÿ òåêñò â áðàóçåð ($curcode =
"Windows-1251";). Ôóíêöèÿ xml_parser_create_ns èìååò äîïîëíèòåëüíûé (òîæå
íåîáÿçàòåëüíûé) ïàðàìåòð, êîòîðûé îáîçíà÷àåò ñèìâîë, êîòîðûì â äîêóìåíòå áóäóò
ðàçäåëÿòüñÿ ïðîñòðàíñòâà èìåí. Ò.ê. íàì ñåé÷àñ ýòî íå íàäî, òî ìû
âîñïîëüçîâàëèñü ïåðâîé ôóíêöèåé. Åñëè ïàðñåð ñîçäàí óñïåøíî, òî ïàðåìåííàÿ $parser
ïîëó÷èò çíà÷åíèå, îòëè÷íîå îò íóëÿ.
Ïîñëå ýòîãî íàäî óêàçàòü ïàðñåðó XML, êàêèå ôóíêöèè âûçûâàòü ïðè ïîÿâëåíèè â
òåêñòå òåãîâ XML. Â íàøåì ïðèìåðå ýòî ñäåëàíî òàê:
// Óñòàíîâèì îáðàáîò÷èêè òåãîâ è òåêñòà ìåæäó íèìè
xml_set_element_handler($parser, 'starthandler', 'endhandler');
xml_set_character_data_handler($parser, 'characterhandler');
Ôóíêöèÿ xml_set_element_handler óñòàíàâëèâàåò îáðàáîò÷èêè äëÿ îòêðûâàþùèõñÿ è
çàêðûâàþùèõñÿ òåãîâ.  êà÷åñòâå ïåðâîãî ïàðàìåòðà èì ïåðåäàåòñÿ ïàðñåð, êîòîðûé
ìû ñîçäàëè äî ýòîãî. À â êà÷åñòâå âòîðîãî è òðåòüåãî - èìåíà ôóíêöèé, êîòîðûå
áóäóò âûçûâàòüñÿ ïî ìåðå òîãî, êàê áóäóò ïîïàäàòüñÿ îòêðûâàþùèåñÿ è
çàêðûâàþùèåñÿ òåãî ñîîòâåòñòâåííî. Ýòè ôóíêöèè äîëæíû áûòü îïðåäåëåíû
îïðåäåëåííûì îáðàçîì. Ôóíêöèÿ äëÿ îòêðûâàþùèõñÿ òåãîâ äîëæíà âûãëÿäåòü ïðèìåðíî
òàê:
// Îáðàáàòûâàåò îòêðûâàþùèåñÿ òåãè
function starthandler ($parser, $name, $attribs)
{
}
Ïðè åå âûçîâå åé ïåðåäàþòñÿ ïàðñåð, êîòîðûé ìû ñîçäàëè, èìÿ îáðàáàòûâàåìîãî òåãà
è åãî àòðèáóòû (òî, ÷òî íàõîäèòñÿ â óãëîâûõ ñêîáêàõ ïîñëå èìåíè). Åñëè ñ èìåíåì
íèêàêèõ îñîáåííîñòåé íåò, òî àòðèáóòû ïåðåäàþòñÿ êàê àññîöèàòèâíûé ìàññèâ, ò.å.
â âèäå êëþ÷ => çíà÷åíèå. Ïîýòîìó ìû èõ è îáðàáàòûâàåì ñëåäóþùèì îáðàçîì:
foreach ($attribs as $atname => $val)
{
echo encoding("$atname => $val");
}
Âñå òîæå ñàìîå è äëÿ çàêðûâàþùèõñÿ òåãîâ, òîëüêî ôóíêöèè íå ïåðåäàþòñÿ àòðèáóòû,
êîòîðûõ â ïðèíöèïå áûòü íå ìîæåò ó çàêðûâàþùåãîñÿ òåãà:
function endhandler ($parser, $name)
{
}
Òóò åñòü îäíà èíòåðåñíàÿ äåòàëü. Äàæå åñëè ó òåãà íåò çàêðûâàþùåãîñÿ, òî âòîðàÿ
ôóíêöèÿ âñå-ðàâíî âûçûâàåòñÿ. Åñëè Âû ïîñìîòðèòå íà ðàáîòó ñêðèïòà, òî óâèäèòå,
÷òî äëÿ òåãà <color/> ó íàñ ïîëó÷èëîñü:
<COLOR>
</COLOR>
À ÷òîáû îáðàáàòûâàòü òåêñò, êîòîðûé ðàñïîëàãàåòñÿ ìåæäó òåãàìè, íàäî óñòàíîâèòü
ñîîòâåòñòâóþùèé îáðàáîò÷èê ôóíêöèåé xml_set_character_data_handler. Åé
ïîëüçîâàòüñÿ òî÷íî òàê æå, òîëüêî åå âòîðûì àðãóìåíòîì äîëæíî áûòü èìÿ ôóíêöèè,
êîòîðàÿ îáúÿâëåíà òàêèì îáðàçîì:
function characterhandler ($parser, $data)
Òî åñòü òàê æå, êàê è äëÿ çàêðûâàþùåãîñÿ òåãà. Èìåííî â íåå ïåðåäàþòñÿ âñå
äàííûå íàïîäîáèå "Íàçâàíèå 1" èëè "Äëèííûé êîììåíòàðèé íà íåñêîëüêî ñòðîê 2" èç
íàøåãî ïðèìåðà. Íó è, íàêîíåö, ñàìîå ãëàâíîå - êàê ÷èòàòü XML-äîêóìåíò.
Îêàçûâàåòñÿ ïðîñòî - êàê îáû÷íûé òåêñòîâûé ôàéë. Ò.å. îòêðûâàåì åãî ôóíêöèåé
fopen, íàïðèìåð òàê:
$fp = fopen ($xmlfilename, "r");
È ÷èòàåì èç íåãî âñå ñòðîêè, êîòîðûå ïîòîì ïåðåäàåì â ôóíêöèþ xml_parse:
while ($data = fread($fp, 4096))
{
if (!xml_parse($parser, $data, feof($fp)))
{
die(sprintf("Îøèáî÷êà âûøëà: %s â ñòðîêå %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
}
}
Ó xml_parse òðè àðãóìåíòà. Ïåðâûé - ïåðåìåííàÿ ñîçäàííîãî íàìè ðàíüøå ïàðñåðà,
âòîðîé - ïðî÷èòàííàÿ ñòðîêà, à òðåòèé (íåîáÿçàòåëüíûé) - ïðèçíàê òîãî, ÷òî ïîðà
çàêàí÷èâàòü ïàðñèòü (âîò ìû òóäà è ïåðåäàåì çíà÷åíèå òîãî, êîí÷èëñÿ ëè ôàéë). Ó
íàñ åùå âñòàâëåíà ïðîâåðêà îøèáîê. Òàì âðîäå âñå ÿñíî èç íàçâàíèÿ.
xml_get_error_code âîçâðàùàåò êîä îøèáêè, ïî êîòîðîìó xml_error_string ñîçäàåò
ñòðîêó, êîòîðàÿ îïèñûâàåò ýòó îøèáêó.
Ïîñëå âñåãî ýòîãî íàäî íå çàáûòü óíè÷òîæèòü ïàðñåð. Ýòî äåëàåòñÿ ôóíêöèåé
xml_parser_free:
xml_parser_free($parser);
Òåïåðü îäíà èç ñàìûõ íåïðèÿòíûõ îñîáåííîñòåé. Ò.ê. ìû ïèñàëè XML êàê Unicode, òî
è ñòðîêè íàì ïåðåäàþòñÿ â òîé æå êîäèðîâêå. À òàê êàê îáû÷íî ñàéò ñòðîÿò íà
áîëåå ïðèâû÷íîé êîäèðîâêå (Koi8, Windows), òî ñ ýòèì Unicod'îì íàäî ÷òî-òî
äåëàòü. È âîò çäåñü íà÷èíàåòñÿ ñàìîå íåïðèÿòíîå.  ðàñøèðåíèè PHP, êîòîðîå
îòâå÷àåò çà XML, åñòü äâå ôóíêöèè äëÿ ïåðåêîäèðîâêè UTF-8. Ýòî ôóíêöèÿ
utf8_decode, êîòîðàÿ ïðåîáðàçóåò ñòðîêó èç UTF-8, è ôóíêöèÿ utf8_encode, êîòîðàÿ
íàîáîðîò ïðåîáðàçóåò â UTF-8. Íî îíè íàì íå ïîäõîäÿò ïî òîé ïðè÷èíå, ÷òî ìîãóò
ðàáîòàòü ñ êîäèðîâêîé ISO-8859-1, â êîòîðîé íåò ðóññêèõ áóêâ. Ê ñ÷àñòüþ,
ðàçðàáîò÷èêè PHP âñå-òàêè ñäåëàëè ôóíêöèè, êîòîðûå ìîãóò áóç ïðîáëåì ðàáîòàòü è
ñ äðóãèìè êîäèðîâêàìè - ýòî mb_convert_encoding.  äàííîì ñëó÷àå ìû åå
èñïîëüçîâàëè òàê:
$str = mb_convert_encoding($str, $curcode, $code);
$curcode è $code ýòî ïåðåìåííûå, â êîòîðûõ õðàíÿòüñÿ íàçâàíèÿ êîäèðîâîê
(ïîìíèòå, ìû èõ ðàíüøå îáúÿâèëè ãëîáàëüíûìè?). Ñ ýòîé ôóíêöèåé âñå ïîíÿòíî:
ïåðâûé àðãóìåíò - ýòî èñõîäíàÿ ñòðîêà, âòîðîé - íàçâàíèå êîäèðîâêè, â êîòîðóþ
ïðåîáðàçóåì, à òðåòèé àðãóìåíò (íåîáÿçàòåëüíûé) - êîäèðîâêà, èç êîòîðîé
ïðåîáðàçóåì. Ôóíêöèÿ âîçâðàùàåò íàì íîâóþ ñòðîêó. Êàçàëîñü áû, ÷òî âñå õîðîøî,
åñòü ôóíêöèÿ, îíà çäîðîâî ðàáîòàåò (ýòî äåéñòâèòåëüíî òàê), íî, ÷òîáû îíà
ðàáîòàëà, íàäî, ÷òîáû áûëî ïîäêëþ÷åíî ðàñøèðåíèå ê PHP - mbstring (multi byte
string). Äëÿ ýòîãî, åñëè âû ðàáîòàåòå èç Windows, â ôàéëå php.ini íàäî
ðàñêîììåíòèðîâàòü ñòðîêó extension=php_mbstring.dll. Íî åñëè äîìà ýòî ñäåëàòü
íåñëîæíî, òî âîò íà õîñòèíãå, ãäå ðàñïîëîæåí Âàø ñàéò, îíî (ðàñøèðåíèå) ìîæåò
áûòü íå ïîäêëþ÷åíî. Èìåííî ïîýòîìó ÿ âûíåñ ïåðåêîäèðîâêó â îòäåëüíóþ ôóíêöèþ,
÷òîáû åå ìîæíî áûëî ëåãêî èñïðàâèòü:
// Ïðåîáðàçóåò ñòðîêó èç Unicode
function encoding ($str)
{
global $code;
global $curcode;
$str = mb_convert_encoding($str, $curcode, $code);
return $str;
}
Åñëè ó Âàñ åñòü èäåè íàñ÷åò òîãî, êàê îáîéòèñü áåç mb_convert_encoding - ïèøèòå
ìíå
Ýòî áûëè ñàìûå ïðîñòûå ôóíêöèè äëÿ ðàáîòû ñ XML. ×òîáû áûëî èíòåðåñíåå, â íàøåì
ñêðèïòå ÿ ñ÷èòàþ óðîâåíü âëîæåííîñòè äëÿ òåãîâ (ýòî äëÿ òîãî, ÷òîáû ïðàâèëüíî
ñìåùàòü òåêñò âïðàâî) è åùå â ãëîáàëüíóþ ïåðåìåííóþ $list çàíîñÿòñÿ
îòêðûâàþùèåñÿ òåãè, à ïðè ïîÿâëåíèè çàêðûâàþùåãîñÿ - âûáðàñûâàåòñÿ ïîñëåäíèé
ýëåìåíò. Ò.î. â $list õðàíèòñÿ ïóòü ïî êîòîðîìó ìû ïðîøëè äî òåêóùåãî òåãà, à
ñàì ýòîò òåã íàõîäèòñÿ â êîíöå ñïèñêà.
Òåïåðü äàâàéòå íåìíîãî ïîáàëóåìñÿ è ïîñìîòðèì, êàê ðàáîòàåò îáðàáîòêà îøèáîê.
Óáåðåì èç òåãà color ñëåø. Òî åñòü îñòàâèì <color>, êàê áóäòî ìû çàáûëè åãî
çàêðûòü. È âîò ÷òî íàì âûäàåò PHP: "Îøèáî÷êà âûøëà: mismatched tag â ñòðîêå 16".
È íà ýòîì îáðàáîòêà ïðåêðàùàåòñÿ. Òàêæå "mismatched tag" áóäåò, åñëè ìû
ïåðåíåñåì çàêðûâàþùèéñÿ òåã <data/> ïîñëå òåãà <foto/>.
Ïîèãðàåìñÿ ñ êîäèðîâêàìè. Åñëè ñîõðàíèòü íàø XML-äîêóìåíò â êîäèðîâêå
Windows-1251 è ÷åñòíî ýòî óêàçàòü â çàãîëîâêå <?xml version="1.0" encoding="Windows-1251"?>
(íå çàáóäüòå èñïðàâèòü ñîîòâåòñòâóþùóþ ãëîáàëüíóþ ïåðåìåííóþ â ñêðèïòå), òî
PHP... áëàãîïîëó÷íî âûëåòàåò :) Ïî êðàéíåé ìåðå, òàê áûëî ó ìåíÿ. ß ýòîò ñêðèïò
èñïûòûâàë íà òàêîé êîíôèãóðàöèè: Win2000 + SP3; Apache 1.3.27; PHP 4.3.1.
Ïîêà âðîäå áû âñå. Åñëè áóäóò âîïðîñû è çàìå÷àíèÿ - ïèøèòå ìíå
Àâòîð íåèçâåñòåí
Ïðè ïåðåïå÷àòêå èíôîðìàöèè äåëàéòå, ïîæàëóéñòà, ññûëêó íà íàø ñàéò
(ëèáî ïîäåëèòüñÿ âêîíòàêòå, ãóãë+ èëè äåëèòåñü â îäíîêëàññíèêàõ ñòàòü¸é). Ñïàñèáî!
Èñòî÷íèê: www.wr-script.ru©, 2004-2026ã.
Äåëèòåñü ñ äðóçüÿìè â ñîöñåòÿõ. Àêòèâíûå êîììåíòàòîðû ïîëó÷àþò ñâåæèå ñêðèïòû è áåñïëàòíûå äîðàáîòêè îò WR-Script.ru!
|
|