Серед плюшок однієї з найбільш поширених скриптових мов, а саме 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<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++.