Простий XML в php5

Серед плюшок однієї з найбільш поширених скриптових мов, а саме 5-ї її версії є також невеличка “регресія”. Чому в лапках – це не є зле, просто видозмінився спосіб передачі параметрів об’єктно-орієнтованих структур порівняно з php4. Наслідок може бути не дуже приємним для когось, – що стосується мене, попередні версії Joomla перестали коректно парсити XML, в них для цього використовується бібліотека domit. В той час, коли багато фреймворків та CMS потребують php5 для коректної роботи, старі скрипти не адаптовані до такого апдейту. Народні хостинги по цій причині мають передвстановлені обидві версії обробника, в себе ж на сервері не знайшов адекватного способу так зробити… Це і тупо трохи.
Позаяк, XML не розбирається, джумла (і 1.0.х і 1.5.х) частково не працює, караул, зате в php5 є свої методи для цього. Спочатку пробував асіліти XML Parser, але не зовсім успішно, в гуглі натикнувся на SimpleXML, як виявилось, є багато інформації про це. Наведу нижче зразки свого бидлокоду, чітко видно різницю в бік спрощення. Також, може комусь знадобиться для переходу, видно аналогію.

Однією з завдань було взяти XML з відкритого джерела з прогнозом погоди на найближчий час. Одним з таких джерел є gismeteo.

< ?xml version="1.0" encoding="UTF-8"?>
<mmweather>
	<report type="frc3">
		<town index="33526" sname="%C8%E2%E0%ED%EE-%D4%F0%E0%ED%EA%EE%E2%F1%EA" latitude="48" longitude="24">
			<forecast day="13" month="10" year="2010" hour="15" tod="2" predict="0" weekday="4">
				<phenomena cloudiness="0" precipitation="10" rpower="0" spower="0"/>
				<pressure max="738" min="736"/>
				<temperature max="9" min="7"/>
				<wind min="2" max="4" direction="7"/>
				<relwet max="58" min="56"/>
				<heat min="7" max="9"/>
			</forecast>
			<forecast day="13" month="10" year="2010" hour="21" tod="3" predict="0" weekday="4">
				<phenomena cloudiness="0" precipitation="10" rpower="0" spower="0"/>
				<pressure max="738" min="736"/>
				<temperature max="-3" min="-1"/>
				<wind min="0" max="2" direction="0"/>
				<relwet max="91" min="89"/>
				<heat min="-3" max="-1"/>
			</forecast>
			<forecast day="14" month="10" year="2010" hour="03" tod="0" predict="0" weekday="5">
				<phenomena cloudiness="0" precipitation="10" rpower="0" spower="0"/>
				<pressure max="738" min="736"/>
				<temperature max="-3" min="-1"/>
				<wind min="0" max="2" direction="2"/>
				<relwet max="93" min="91"/>
				<heat min="-4" max="-2"/>
			</forecast>
			<forecast day="14" month="10" year="2010" hour="09" tod="1" predict="0" weekday="5">
				<phenomena cloudiness="0" precipitation="10" rpower="0" spower="0"/>
				<pressure max="737" min="735"/>
				<temperature max="1" min="-1"/>
				<wind min="0" max="2" direction="2"/>
				<relwet max="80" min="78"/>
				<heat min="-1" max="1"/>
			</forecast>
		</town>
	</report>
</mmweather>

Було:

require_once( $mosConfig_absolute_path . '/includes/domit/xml_domit_lite_include.php' );
//$cache_time	 = "3600";
$cityid	 = 33526;
$sutkiimg = array("night","day","day","night");
 
$oblakaimg = array("clear","mostlyclear","cloudy","morecloudy","showers","rain","snowing","snowing","thunders","na","haze");
$template_file = $mosConfig_absolute_path."/components/com_weather/template.txt";
$gis_addr = "http://informer.gismeteo.ru/xml/{$cityid}_1.xml";
 
$template = file_get_contents( $template_file );
$result = "";
	$xmlDoc =& new DOMIT_Lite_Document();
	$xmlDoc->resolveErrors( true );
	if ($xmlDoc->loadXML( $gis_addr, false, true )) {		$element = &$xmlDoc->documentElement;
		if ($element->getTagName() == 'MMWEATHER') {			if( $report = &$xmlDoc->getElementsByPath( 'REPORT', 1 ) ) {				if( $town = $report->getElementsByPath( 'TOWN', 1 ) ) {					for( $k=1;
 $k&lt;5;
 $k++ ) {				$forecast = $town->getElementsByPath( 'FORECAST', $k ) ;
						$day = $forecast->getAttribute('day');
						$month = $ru_monthes[$forecast->getAttribute('month')];
						$year = $forecast->getAttribute('year');
						$tod = $sutki[$forecast->getAttribute('tod')];
						$todimg = $sutkiimg[$forecast->getAttribute('tod')];
						$hour = $forecast->getAttribute('hour');
						$temperature = $forecast->getElementsByPath( 'TEMPERATURE', 1 );
						$min_temperature = $temperature->getAttribute('min');
						$max_temperature = $temperature->getAttribute('max');
						$pressure = $forecast->getElementsByPath( 'PRESSURE', 1 );
						$min_pressure = $pressure->getAttribute('min');
						$max_pressure = $pressure->getAttribute('max');
						$wind = $forecast->getElementsByPath( 'WIND', 1 );
						$wind_direction = $winds[ $wind->getAttribute('direction') ];
						$min_wind = $wind->getAttribute('min');
						$max_wind = $wind->getAttribute('max');
						$relwet = $forecast->getElementsByPath( 'RELWET', 1 );
						$min_relwet = $relwet->getAttribute('min');
						$max_relwet = $relwet->getAttribute('max');
						$heat = $forecast->getElementsByPath( 'HEAT', 1 );
						$min_heat = $heat->getAttribute('min');
						$max_heat = $heat->getAttribute('max');
						$phenomena = $forecast->getElementsByPath( 'PHENOMENA', 1 );
						$cloudiness = $oblaka[$phenomena->getAttribute('cloudiness')];
						$cloudinessimg = $oblakaimg[$phenomena->getAttribute('cloudiness')]."_".$todimg;
						$precipitation = $oblaka[$phenomena->getAttribute('precipitation')];
						$precipitationimg = $oblakaimg[$phenomena->getAttribute('precipitation')]."_".$todimg;
												eval("\$result .= \"{$template}\";
");
					}				}			}		} else echo _WR_ERRINCXML;
	} else echo _WR_ERRNOTOPEN;

Код кривуватий, взятий з старого бекапу на локальному сервері, в стані тогочасної відладки, але це не принципово.

Стало:

$cityid	 = 33526; //ivano-frankivsk
 
$sutkiimg = array("night","day","day","night"); //prefixes for images by time of day
$oblakaimg = array("clear","mostlyclear","cloudy","morecloudy","showers","rain","snowing","snowing","thunders","na","haze"); // for cloudness
$template_file = $mosConfig_absolute_path."/components/com_weather/template.txt";
$gis_addr = "http://informer.gismeteo.ru/xml/{$cityid}_1.xml";
 
$template = file_get_contents( $template_file );
$result = "";
 
if ($xml = file_get_contents( $gis_addr )){ //getting file from remote server
	if ($data=simplexml_load_string($xml)){ //load into simple xml php5 object
		foreach ($data->REPORT->TOWN->FORECAST as $forecast){
 
			$day = $forecast['day'];
			$month = $ru_monthes[intval($forecast['month'])];
			$year = $forecast['year'];
			$tod = $sutki[intval($forecast['tod'])];
			$todimg = $sutkiimg[intval($forecast['tod'])];
			$hour = $forecast['hour'];
 
			$temperature=$forecast->TEMPERATURE;
			$min_temperature = $temperature['min'];
			$max_temperature = $temperature['max'];
 
			$pressure = $forecast->PRESSURE;
			$min_pressure = $pressure['min'];
			$max_pressure = $pressure['max'];
 
			$wind = $forecast->WIND;
			$wind_direction = $winds[intval($wind['direction'])];
			$min_wind = $wind['min'];
			$max_wind = $wind['max'];			
 
			$relwet = $forecast->RELWET;
			$min_relwet = $relwet['min'];
			$max_relwet = $relwet['max'];
 
			$heat = $forecast->HEAT;
			$min_heat = $heat['min'];
			$max_heat = $heat['max'];			
 
			$phenomena = $forecast->PHENOMENA;
			$cloudiness = $oblaka[intval($phenomena['cloudiness'])];
			$cloudinessimg = $oblakaimg[intval($phenomena['cloudiness'])]."_".$todimg;
			$precipitation = $oblaka[intval($phenomena['precipitation'])];
			$precipitationimg = $oblakaimg[intval($phenomena['precipitation'])]."_".$todimg;			
 
			eval("\$result .= \"{$template}\";"); //parsing template part
		}
	} else echo _WR_ERRINCXML; 
} else echo _WR_ERRNOTOPEN;

Це є функціональні частини компонента погоди, для CMS, яка колись була joomla 1.0.15. Тому решта обв’язки непотрібно приводити, там специфічні суто заголовки і вивід.

Можна покритикувати, поділитись досвідом, задати питання. Але найцікавіше – хто який знає адекватний інструмент для intendation php та html коду, для linux :) бажано. Не лише покласти відступи, а і попереносити теги\оператори. Колись використовував плагін до notepad++, але що то за плагін і як називається пішло у небуття разом з notepad++.

This entry was posted in Просто інформація. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

You must be logged in to post a comment.