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