Cs

Z BWpedia
Przejdź do nawigacji Przejdź do wyszukiwania

PROPOZYCJE STANDARDU KODOWANIA

Ścieżki

  1. Wszystkie podane katalogi wskazane są relatywnie do katalogu głównego skryptu.
  2. Wszystkie klasy znajdują się w katalogu classes/ oraz mają nazwy identyczne jak nazwa klasy (ważna jest wielkość liter!), przykład: PierwszaKlasa.php
  3. Pliki językowe znajdują się w katalogu language/. Nazwa pliku zawiera 2 litery charakterystyczne dla języka, znak _ oraz kategorię językową, np. pl_parts.php. Do obsługi plików językowych służy klasa Language (singleton).
  4. Pliki z danymi specyficznymi dla projektu znajdują się w katalogu data/. Do obsługi tych danych służy klasa DataCollector (singleton).
  5. Szablony znajdują się się w katalogu smarty/templates/. Do obsługi szablonów używana jest klasa MySmarty, dodatkowo główna aplikacja może korzystać z singletona MainTemplate.
  6. Wszystkie pozostałe pliki źródłowe znajdują się w katalogu głównym.

Konwencje nazewnicze

  • Każda nazwa klasy powinna rozpoczynać się wielką literą, każdy następny człon nazwy również (np MainTemplate).
  • Każda funkcja/metoda/zmienna/pole klasy powinny rozpoczynać się małą literą, każdy następny człon nazwy wielką (np. $myGreatVariable).

Przykład:

class ObiektKlasy
{
	private $poleKlasy;
	public $drugiePoleKlasy;
		
	//...
	public function metodaKlasy
	{
		//EMPTY BODY
	}
	//...
}

	$nowyObiekt=new ObiektKlasy();
	$nowaZmienna=$nowyObiekt->getJakiesPole();
  • Każde celowo puste ciało pętli, funkcji etc. powinno być odpowiednio oznaczone. Dzięki temu ktoś, kto będzie czytać kod i zobaczy np. pustą pętlę, nie będzie się zastanawiał, czy tak musi być, czy jest to przeoczenie programisty, czy też powinien to sam zaimplementować. Przykład zaprezentowany powyżej (//EMPTY BODY).

Zapytania SQL

  • wszystkie polecenia SQL powinny być pisane dużymi literami (SELECT, INSERT, SET, WHERE, LIMIT itd)
  • wszystkie nazwy pól powinny być zawarte między znakami ``, np. `actExp`, `id`
  • wszystkie wartości pól powinny być zawarte między znakami (chyba, że używana jest funkcja $db->quote()).
  • jeśli oczekujemy że zapytanie zwróci znaną przez nas liczbę rekordów (np równą jakiejś zmiennej lub liczbie), należy zastosować LIMIT, przykładowo dla 1 rekordu:
SELECT * FROM `tabela` LIMIT 1;
  • każde zapytanie zawarte w kodzie PHP powinno być przyporządkowane do jakiejś zmiennej (np $query), ułatwia to obsługę błędów (np poprzez wypisanie zawartości zapytania). Każde zapytanie powinno kończyć się średnikiem.
	$query = "treść zapytania;";
	$rezultat = $db->exec(query);
	echo $query; // DEBUG

Obsługa błędów i wyjątki

  • W żadnym skrypcie bezpośrednio związanym z projektem gry (oprócz skryptów wykonywanych niezależnie od użytkownika np skryptu aktualizacji rankingu) nie powinno pojawić się exit ani die. Zamiast tego powinien zostać rzucony wyjątek.

Przykład:

	$db->beginTransaction();
	$query = "UPDATE `chars` SET `actExp`=`actExp`+'$expDst' WHERE `id`='$me->id' LIMIT 1;";
	$rows = $db->exec($query);
	if ($rows != 1) { 
		$db->rollBack(); 
		throw new Exception($query); 
	}
	$db->commit();

UWAGA!!!

Rzucenie wyjątku oznacza przerwanie skryptu, wylogowanie użytkownika oraz wysłanie komunikatu o błędzie na maila kg@bwteam.pl. W związku z tym należy to robić tylko wtedy, gdy przewiduje się, że dane zachowanie skryptu oznacza błąd, w wyniku wystąpienia którego skrypt pod żadnym pozorem nie może być kontynuowany.

  • W przypadku wielokrotnych instrukcji warunkowych (poziom zagłębienia powyżej 3), powinniśmy utworzyć funkcję sprawdzającą każdy warunek po kolei oraz zwracającą false w przypadku gdy dalsze sprawdzanie nie może być wykonywane lub nie jest potrzebne. Przykład:
function funkcjaSprawdzajaca($playerId, $playerName) 
{
	global $smarty;
	$db = Database::getInstance();
	$lang = Language::getInstance();

	if ($playerId == $me->id) {
		$smarty->assign('error', $lang->trade_cantOfferYourself);
		return false;
	}

	// sprawdz czy taki gracz w ogole istnieje
	$query = "SELECT `name` FROM `chars` WHERE `id`='$playerId' LIMIT 1;";
	$playerName = $db->get($query);
		
	if (!$playerName) {
		$smarty->assign('error', $lang->trade_invalidPlayerId);
		return false;
	}
	
	// dalszy kod który wykona się w przypadku niewystąpienia tych błędów
	...
	return true; // wszystko ok
}

Klamry i formatowanie kodu

  • Każdy blok kodu zaznaczony klamrami { i } powinien zaczynać się od nowej linii, a instrukcje/deklaracje w nim zawarte powinny zaczynać się od tabulacji. Bardzo pomocne w zachowaniu tego punku standardu jest ustalone standardowo formatowanie kodu środowiska Eclipse.
  • W przypadku pętli ustalamy że możliwe są dwie konwencje:
	if (warunek) {
		// tresc
	}

lub

	if (warunek) 
	{
		// tresc
	}
  • W przypadku funkcji ustalamy że otwierająca klamra ma znajdować się zawsze w nowej linijce:
function jakasFunkcja()
{
	// ciało
}

Niezaklasyfikowane/pozostałe

  1. Każda pętla lub instrukcja warunkowa powinna dotyczyć bloku pomiędzy dwoma klamrami ({ i }). Język pozwala pominąć klamry w pętlach i instrukcjach warunkowych, jeśli dotyczą pojedynczej linijki zakończonej znakiem ';'. Mimo to zastosowanie nawet w tym przypadku klamer ma dwie zalety. Po pierwsze poprawia czytelność kodu, a po drugie sprawia, że na pewno nie zapomnimy o dostawieniu klamer, jeśli liczba instrukcji w pętli zwiększy się.
  2. Każdy blok switch powinien zawierać etykietę default. Jeśli nie ma sensownej logiki do umieszczenia w tej etykiecie, to kod w niej zawarty będzie obsługiwał nieprzewidziane wartości sprawdzanego wyrażenia. Nie da się przewidzieć wszystkiego - nawet, jeśli ktoś robi switch na zmienną wyliczeniową, która może przyjmować tylko kilka wartości, to przecież nikt nie powiedział, że nie trzeba będzie kiedyś tego typu rozszerzyć - wtedy taki default wychwyci ewentualne zapomnienia w uzupełnieniu instrukcji switch. Jeśli warunek default nie powinien się nigdy zdarzyć w danej konstrukcji switch, obsługa takiego nieprzewidzianego powinna polegać na rzuceniu wyjątku wraz z treścią wskazującą na wartość sprawdzanego parametru.