Cs
Przejdź do nawigacji
Przejdź do wyszukiwania
PROPOZYCJE STANDARDU KODOWANIA
Ścieżki
- Wszystkie podane katalogi wskazane są relatywnie do katalogu głównego skryptu.
- Wszystkie klasy znajdują się w katalogu classes/ oraz mają nazwy identyczne jak nazwa klasy (ważna jest wielkość liter!), przykład: PierwszaKlasa.php
- 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).
- Pliki z danymi specyficznymi dla projektu znajdują się w katalogu data/. Do obsługi tych danych służy klasa DataCollector (singleton).
- 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.
- 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
- 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ę.
- 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.