[PHP] Pogodynka generująca błąd na stronie


(Lukpio3) #1

Witam Serdecznie,

Mam problem ze stroną. Generuje go pogodyna (moduł wyświetlający pogodę na stronie) Otóż po wejściu na stronę czasem generowany jest następujący komunikat błędu:

« MODx Parse Error »

MODx encountered the following error while attempting to parse the requested resource:

« PHP Parse Error »


PHP error debug

  Error: simplexml_load_string() [function.simplexml-load-string]: Entity: line 1: parser error : Start tag expected, '<' not found   

  Error type/ Nr.: Warning - 2   

  File: /home/users/gminaleszno/public_html/assets/snippets/pogodynka/pogodynka.php   

  Line: 163   

  Line 163 source: $pogodaXml = simplexml_load_string($pogodaXml);

Może potraficie jakoś pomóc bo ja w tym pliku pogodynka.php nic nie widzę. Wszystko jest ok. A może błąd jest generowany z innego powodu? Najdziwniejsze jest to że pojawia się to nie raz i zawsze jak odświeżę stroną, wszystko wraca do normy i wyświetla się ona prawidłowo. Jeszcze wkleję tu zawartość pliku pogodynka.php. W pliku do kodu są porobione komentarze. Ja naprawdę nie wiem co tu może krzaczyć. Może Wy coś podpowiecie.

<?php


class Pogoda

{


	/**

	 * Czy wszystko dziala bezblendnie?

	 * @var bool

	 */

	public $bezBlendow = TRUE;


	/**

	 * Tablica z danymi o pogodzie

	 * @var bool

	 */

	public $tPogoda = array();


	/**

	 * Aktualna miejscowosc

	 * @var string

	 */

	private $miejscowosc;


	/**

	 * Format daty wyswietlanej uzytkownikowi, z funkcji date()

	 * @var string

	 */

	private $formatDaty = 'd.m.Y'; // date();



	/**

	 * Ustawia miejscowosc ktorej pogoda ma byc wyswietlona

	 * @param string $nazwaMiejscowosci nazwa miejscowosci

	 */

	public function ustawMiejscowosc ($nazwaMiejscowosci)

	{


		$this->miejscowosc = $nazwaMiejscowosci;

	}


	/**

	 * Ustawia format daty uzywanej w pogodzie

	 * @param string $formatDaty format daty zaczerpniety z funkcji date()

	 */

	public function ustawFormatDaty ($formatDaty)

	{


		if ($formatDaty != '')

		{

			$this->formatDaty = $formatDaty;

		}

	}


	/**

	 * Ustawia własne obrazki (zamiast tych dostarczanych przez google)

	 * @param string $folderZobrazkami folder z obrazkami, adres wzgledny lub bezwzgledny w formie np. "http://domena.pl/obrazki", "obrazki/pogoda" (bez slasha na koncu)

	 * @param bool $pokazywacDomyslne Czy w razie braku wlasnego obrazku wyswietlac ten od google ?

	 * @param string $formatObrazkow format wlasnych obrazkow np. "png"

	 * @param array $tObrazkiPogody tablica z obrazkami pogody np. array()

	 */

	public function ustawObrazkiPogody ($folderZobrazkami, $pokazywacDomyslne, $formatObrazkow, $tObrazkiPogody)

	{


		$this->obrazkiFolder = $folderZobrazkami . '/';

		$this->obrazkiPokazywacDomyslne = $pokazywacDomyslne;

		$this->obrazkiTPogody = $tObrazkiPogody;

		$this->obrazkiFormat = '.' . $formatObrazkow;

	}


	/**

	 * Przetwarza pogode na podstawie ustawien

	 */

	public function wykonaj ()

	{


		$pogodaXml = $this->pobierzDane();


		if (! empty($pogodaXml))

		{

			$this->tPogoda = $this->przetworz($this->pogodaXmlDoTablicy($pogodaXml));

		}

		else

		{

			$this->bezBlendow = FALSE;

		}


	}


	/**

	 * Zwraca pogode w formie tablicy

	 * @return array tablica z danymi o pogodzie

	 */

	public function jakoTablica ()

	{


		return $this->tPogoda;

	}


	/**

	 * Zwraca pogode w formie obiektów

	 * @return stdClass obiekt z danymi o pogodzie

	 */

	public function jakoObiekt ()

	{


		return $this->tablicaDoObiektu($this->tPogoda);

	}


	/**

	 * Pobiera dane o pogodzie ze strony google

	 * @return string plik xml z danymi o pogodzie

	 */

	private function pobierzDane ()

	{


		return @file_get_contents("http://www.google.pl/ig/api?weather=$this->miejscowosc&oe=utf-8");


	}


	/**

	 * Konwertuje obiekt SimpleXMLElement do tablicy

	 * @param SimpleXMLElement $arrObjData obiekt klasy SimpleXMLElement

	 * @author svdmeer@xs4all.nl, http://www.php.net/manual/en/book.simplexml.php#98054

	 * @return array tablica z danymi z pliku XML

	 */

	private function xml2array ($arrObjData, $arrSkipIndices = array())

	{


		$arrData = array();


		if (is_object($arrObjData))

		{

			$arrObjData = get_object_vars($arrObjData);

		}


		if (is_array($arrObjData))

		{

			foreach ($arrObjData as $index => $value)

			{

				if (is_object($value) || is_array($value))

				{

					$value = $this->xml2array($value, $arrSkipIndices); // recursive call

				}

				if (in_array($index, $arrSkipIndices))

				{

					continue;

				}

				$arrData[$index] = $value;

			}

		}

		return $arrData;


	}


	/**

	 * Tworzy obiekt SimpleXMLElement, konwertuje plik xml do tablicy, wycina zbedne dane i zwraca tablice pliku XML

	 * @param string $pogodaXml pogoda w formie pliku XML

	 * @return array tablica z danymi z pliku XML

	 */

	private function pogodaXmlDoTablicy ($pogodaXml)

	{


		$pogodaXml = simplexml_load_string($pogodaXml);


		$tPogoda = $this->xml2array($pogodaXml);


		return $tPogoda['weather'];

	}


	/**

	 * Przetwarza tablice XML do formatu bardziej czytelnego dla czlowieka

	 * @param array $tPogoda tablica z pliku XML

	 * @return array tablica z danymi o pogodzie, bardziej czytelna dla czlowieka

	 */

	private function przetworz ($tPogoda)

	{


		$pogoda = array();


		$city = explode(', ', $tPogoda['forecast_information']['city']['@attributes']['data']);


		$pogoda['miejscowosc'] = $city[0];

		$pogoda['wojewodztwo'] = $city[1];


		$current_date_time = explode(' ', $tPogoda['forecast_information']['current_date_time']['@attributes']['data']);


		$pogoda['warunkiTeraz'] = array();


		$pogoda['warunkiTeraz']['data'] = $this->dodajDoDaty($current_date_time[0], 0);

		$pogoda['warunkiTeraz']['dzien'] = $this->dzienTygodnia($current_date_time[0]);

		$pogoda['warunkiTeraz']['opisWarunkow'] = $tPogoda['current_conditions']['condition']['@attributes']['data'];

		$pogoda['warunkiTeraz']['temperatura'] = $tPogoda['current_conditions']['temp_c']['@attributes']['data'];

		$pogoda['warunkiTeraz']['wilgotnosc'] = str_replace('Wilgotność: ', '', $tPogoda['current_conditions']['humidity']['@attributes']['data']);

		$pogoda['warunkiTeraz']['wiatr'] = $tPogoda['current_conditions']['wind_condition']['@attributes']['data'];

		$pogoda['warunkiTeraz']['ikonaNazwa'] = $this->ikonaSamaNazwa($tPogoda['current_conditions']['icon']['@attributes']['data']);


		if (isset($this->obrazkiFolder))

		{

			$pogoda['warunkiTeraz']['ikona'] = $this->ikonaWlasna($pogoda['warunkiTeraz']['ikonaNazwa']);

		}

		else

		{

			$pogoda['warunkiTeraz']['ikona'] = $this->ikonaUrl($tPogoda['current_conditions']['icon']['@attributes']['data']);

		}


		$pogoda['warunkiKolejneDni'] = array();

		$i = 1;


		foreach ($tPogoda['forecast_conditions'] as $dzien)

		{


			$__dzien = array();


			$__dzien['data'] = $this->dodajDoDaty($pogoda['warunkiTeraz']['data'], $i);

			$__dzien['skrotDnia'] = $dzien['day_of_week']['@attributes']['data'];

			$__dzien['dzien'] = $this->dzienTygodnia($__dzien['data']);

			$__dzien['temperaturaMinimalna'] = $dzien['low']['@attributes']['data'];

			$__dzien['temperaturaMaksymalna'] = $dzien['high']['@attributes']['data'];

			$__dzien['opisWarunkow'] = $dzien['condition']['@attributes']['data'];

			$__dzien['ikonaNazwa'] = $this->ikonaSamaNazwa($dzien['icon']['@attributes']['data']);


			if (isset($this->obrazkiFolder))

			{


				$__dzien['ikona'] = $this->ikonaWlasna($__dzien['ikonaNazwa']);

			}

			else

			{

				$__dzien['ikona'] = $this->ikonaUrl($dzien['icon']['@attributes']['data']);

			}


			$pogoda['warunkiKolejneDni'][] = $__dzien;


			++ $i;

		}


		return $pogoda;

	}


	// -----------------------------

	// >>>>> poboczne funkcje <<<<<<

	// -----------------------------



	/**

	 * Przetwarza wlasna ikone zgodnie z ustawieniami

	 * @param string $ikonaNazwa nazwa ikony bez rozszerzenia

	 * @return string obrazek pogody wedlug wlasnych ustawien

	 */

	private function ikonaWlasna ($ikonaNazwa)

	{


		if (in_array($ikonaNazwa, $this->obrazkiTPogody))

		{

			return $this->obrazkiFolder . $ikonaNazwa . $this->obrazkiFormat;

		}

		elseif ($this->obrazkiPokazywacDomyslne)

		{

			return "http://www.google.pl/ig/images/weather/$ikonaNazwa.gif";

		}


	}


	/**

	 * Dopisuje domene do adresu wzglednego obrazka z wizualizacja pogody

	 * @param string $url wzgledny adres obrazka

	 * @return string bezwzgledny adres url obrazka

	 */

	private function ikonaUrl ($url)

	{

	    $nazwa = $this->ikonaSamaNazwa($url);

		if(empty($nazwa)) $nazwa = "unknown";

		return "images/pogoda/$nazwa.png";


	}


	/**

	 * Wyciąga z adresu wzglednego sama nazwe pliku ikony

	 * @param string $ikona wzgledny adres obrazka

	 * @return string nazwa pliku ikony

	 */

	private function ikonaSamaNazwa ($ikona)

	{


		$pos = strripos($ikona, "/");

		$ikona = substr($ikona, $pos + 1);

		$pos = strripos($ikona, '.');

		return substr($ikona, 0, $pos);

	}


	/**

	 * Dodaje do daty x dni, oraz formatuje w wybrany przez uzytkownika sposob

	 * @param string $data data zapisana w formacie Y-m-d

	 * @param int $ileDodacDni ilosc dni do dodania

	 * @return string data z dodana iloscia dni i ustalonym formacie

	 */

	private function dodajDoDaty ($data, $ileDodacDni)

	{


		return date($this->formatDaty, strtotime($data . " + $ileDodacDni day"));

	}


	/**

	 * Konwersja tablicy do obiektu, wraz z podtablicami

	 * @param array $array tablica

	 * @return stdClass obiekt z danymi z tablicy

	 */

	private function tablicaDoObiektu ($tablica)

	{


		foreach ($tablica as $klucz => $wartosc)

		{

			if (is_array($wartosc))

				$tablica[$klucz] = $this->tablicaDoObiektu($wartosc);

		}

		return (object) $tablica;

	}


	/**

	 * Zwraca dzien tygodnia w formie pelnej np. Poniedzialek

	 * @param string $data data

	 * @return string dzien w formie pelnej

	 */

	private function dzienTygodnia ($data)

	{


		$dzien = date("w", strtotime($data));


		switch ($dzien)

		{


			case 0:

				$dzien = "Niedziela";

				break;


			case 1:

				$dzien = "Poniedziałek";

				break;


			case 2:

				$dzien = "Wtorek";

				break;


			case 3:

				$dzien = "Środa";

				break;


			case 4:

				$dzien = "Czwartek";

				break;


			case 5:

				$dzien = "Piątek";

				break;


			case 6:

				$dzien = "Sobota";

				break;


		}

		return $dzien;

	}


}

?>

Żeby się lepiej czytało dodaję jeszcze kod wklejony tu: http://wklej.org/id/815579/


(nnick) #2

Może po prostu czasem ma problem z pobraniem i w takim przypadku zmienna $pogodaXml jest pusta, więc nie ma co w niej parsować i wywala błąd. Dorzuć sprawdzenie czy string nie jest pusty.


(Lukpio3) #3

Wiesz co, najprawdopodobniej tak jest. Jeszcze jakbyś mógł podpowiedzieć w którym miejscu powinienem to wstawić to było by super. Przepraszam że pytam ale mam kiepskie doświadczenie jeśli chodzi o php. Druga sprawa, jak nie jest pusta ok, wyświetla pogodę a gdy jest pusta to co dać?


(nnick) #4

Nie wiem na ile to będzie prawidłowe w PHP (nie jestem programistą PHP, wniosek co do błędu wyciągnąłem z praktyki z innymi językami):

private function pogodaXmlDoTablicy ($pogodaXml)

	{

                            if(empty($pogodaXml))

                                        return NULL;


		$pogodaXml = simplexml_load_string($pogodaXml);

		$tPogoda = $this->xml2array($pogodaXml);

		 return $tPogoda['weather'];

	}

No i w we wszystkich wywołaniach tej funkcji musisz sprawdzić co funkcja zwróciła (tablicę czy NULL'a) i odpowiednio w przypadku NULL'a zareagować (na przykład poinformować użytkownika o błędzie, albo spróbować jeszcze raz pobrać dane z serwera.


(Drobok) #5

Multum bezsensownych funkcji przez co czytelność kodu jest naganna :slight_smile:

wykonaj sprawdza to co chcesz dopisać do innej funkcji (ctrl+f rulez) :stuck_out_tongue:

Jak wywołujesz tą klasę ? :slight_smile:


(Lukpio3) #6

Klasa wywoływana jest w sposób następujący:

[!pogodynka!]
[/code]


(Drobok) #7

http://pl.wikibooks.org/wiki/PHP/Klasy_i_obiekty

Pewnie masz jakiś szablon / cms. Ta linia, nie wywołuje tej klasy, a jedynie jest znakiem do wykonania kodu dla innego pliku (przypuszczenie, bo skoro to działa to jakiś plik musi ten ciąg podmieniać)

-- Dodane 22.08.2012 (Śr) 12:05 --

Dodając:

error_reporting(E_ALL);

$klasa = new Pogoda();

$klasa->ustawMiejscowosc("Katowice");

$klasa->wykonaj();

Przed zamknięcie php, żadnych błędów nie wywala :slight_smile: Pewnie masz problem z ustawieniem miasta (wtedy są błędy) :slight_smile:


(Lukpio3) #8

Ale to ustawienie miasta słuchaj jest w tym pliku co dałem czy powinno być gdzie indziej? Bo mówiąc szczerza ja tu nic nie widzę. Druga sprawa to podmieniłem sobie w tym linku google.com/api ..... i wpisałem na sztywno warszawę i błąd nadal jest.