Jeśli chcesz uczestniczyć w rozwoju WP STAGING, zapoznaj się z poniższymi wytycznymi kodowania i najlepszymi praktykami.
- Używaj PSR https://www.php-fig.org/psr/.
- Używaj krótkiej składni Array [].
- Używaj camelCase dla nazw zmiennych.
- Używaj StudlyCaps dla nazw klas.
- Używaj podkreśleń w nazwach plików i folderów.
- Unikaj inline-conditions.
- Skróty stosuj rzadko! Nie używaj skrótów niezatwierdzonych przez zespół ani nie wymyślaj własnych, niepopularnych skrótów przy nazywaniu właściwości czy metod.
- Nazwy klas, metod i właściwości powinny dokładnie wyjaśniać ich przeznaczenie.
Clean Code
- Całkowity koszt utrzymywania bałaganu rośnie z czasem.
- Bardzo trudno przebudować legacy system od zera. Refactoring i drobne, przyrostowe ulepszenia to często lepsza droga.
- W zabałaganionym kodzie zadania, które powinny zająć godziny, mogą zająć dni lub tygodnie.
- Poświęć czas, by działać szybko.
- Czysty kod robi jedną rzecz dobrze. Zły kod próbuje zrobić za dużo.
- Czysty kod jest dobrze przetestowany.
- Czytając dobrze napisany kod, każda funkcja robi mniej więcej to, czego się spodziewałeś.
- Jeśli nie zgadzasz się z zasadą, której uczy ktoś z wieloletnim doświadczeniem, warto przynajmniej rozważyć jego punkt widzenia, zanim go odrzucisz.
- Kod jest dużo częściej czytany niż pisany.
- Kod, który łatwiej się czyta, łatwiej się zmienia.
- Zostaw kod w lepszym stanie, niż go zastałeś (zasada skauta).
Komentarze i docBlocki
- Komentarze mogą kłamać. Mogą być błędne od początku lub stać się nieaktualne, gdy kod ewoluuje. Np. przy zmianie nazwy lub refactoringu metody zawsze sprawdzaj, czy komentarz jest nadal aktualny.
- Używaj komentarzy, by opisywać dlaczego coś jest napisane tak, a nie inaczej, a nie żeby wyjaśniać co się dzieje.
- Komentarzy często można uniknąć dzięki jasnym nazwom zmiennych i wyodrębnianiu sekcji kodu do jasno nazwanych funkcji.
- Stosuj spójny prefiks dla komentarzy TODO, by łatwiej je było wyszukiwać. Okresowo wracaj do nich i czyść.
- Nie używaj docBlocków dla samej idei używania ich. Komentarze opisujące, co robi metoda, jakie przyjmuje argumenty i co zwraca, są często co najwyżej zbędne, a w gorszym wypadku mylące.
- Komentarze powinny zawierać wszystkie istotne informacje i kontekst potrzebny czytającemu. Nie bądź leniwy ani enigmatyczny.
- Komentarze typu „dziennik zmian” czy „autor pliku” są zbędne dzięki version control i git blame.
- Nie komentuj martwego kodu. Po prostu go usuń. Jeśli sądzisz, że kiedyś go potrzebujesz — od tego jest version control.
- Komentuj tyle, ile to konieczne, ale jak najmniej. Jeśli po napisaniu metody odczuwasz silną potrzebę dodania komentarza, najczęściej nazwa metody jest niewystarczająco jasna lub kod robi więcej niż jedną rzecz. W takim wypadku rozważ refactoring zamiast pisać komentarz.
Styl kodu
Spacje wokół operatorów binarnych
Operatory binarne „=” i „=>” powinny być otoczone spacjami. W ustawieniach stylu kodu IDE jest opcja autoformatowania, która pozwala wyrównywać przypisania kluczy/wartości w ten sposób:
$array = [
$var => 'foo',
$varvar => 'foo'
];
$var = 1;
$var100 = 100;
$var2000 = 2000;
To zgrabna sztuczka, która ułatwia czytanie większych fragmentów podobnego kodu.
Warunki Yody
Zagłosowaliśmy, by nie używać warunków Yody ze względu na czytelność.
Niezalecane:
if ( true === $var ) {}
Zalecane:
if ( $var === true ) {}
Native function/constant invocation
Native invocation to technika dodawania wiodącego ukośnika (\) przed wywołaniem funkcji/stałej, aby przyspieszyć resolwowanie. Dzięki temu PHP nie musi sprawdzać, czy funkcja/stała pochodzi z namespace, czy jest natywna.
Zagłosowaliśmy, by nie używać techniki Native function/constant invocation — ze względu na czytelność i mniejszą podatność na błędy w naszym kodzie.
W niektórych przypadkach dozwolone jest jej użycie — ostrożne i przemyślane.
Niezalecane:
if ( \is_array($var) ) {}
if ( \PHP_SAPI === 'cli') {}
Zalecane:
if ( is_array($var) ) {}
if ( PHP_SAPI === 'cli') {}
Namespace’y i nazwy klas
Zgodnie z zasadami programowania obiektowego (OOP) nazwy klas powinny być rzeczownikami, ponieważ reprezentują obiekty lub koncepcje w systemie. Pomaga to uczynić kod bardziej czytelnym i zrozumiałym dla innych deweloperów.
Warto jednak zauważyć, że niektóre języki programowania, w tym PHP, pozwalają używać czasowników jako nazw klas. W takich przypadkach czasownik wskazuje zwykle, że klasa reprezentuje akcję lub zachowanie zamiast obiektu.
Na przykład klasa o nazwie „Mailer” może reprezentować obiekt, który wysyła e-maile, podczas gdy klasa o nazwie „SendMail” może reprezentować zachowanie wysyłające e-maile. Choć technicznie używanie czasowników jako nazw klas jest dozwolone, może to utrudnić czytanie i rozumienie kodu — zwykle odradza się to na rzecz rzeczowników.
- Dozwolone są wyłącznie znaki a-z, A-Z i 0-9 dla nazw namespace’ów i klas.
- Namespace’y są zwykle zapisywane w UpperCamelCase, ale dozwolone są warianty dla utrwalonych nazw i skrótów.
- Nazwy klas są zawsze zapisywane w
UpperCamelCase. - Niekwalifikowana nazwa klasy musi być rozumiana dosłownie, nawet bez namespace.
- Głównym celem namespace’ów jest kategoryzacja i porządkowanie.
- Nazwy klas muszą być rzeczownikami, nigdy przymiotnikami.
- Nazwa klas abstrakcyjnych musi zaczynać się od słowa „Abstract”, a nazwy klas aspektów muszą kończyć się słowem „Aspect”.
Niepoprawne nazewnictwo namespace’ów i klas:
| W pełni kwalifikowana nazwa klasy | Nazwa niekwalifikowana | Uwagi |
|---|---|---|
| WPStaging\Framework\Session\Php | Php | Klasa nie jest reprezentacją PHP |
| WPStaging\Framework\Cache\Backend\File | File | Klasa nie reprezentuje pliku! |
| WPStaging\Framework\Session\Interface | Interface | Niedozwolone, „Interface” to zarezerwowane słowo kluczowe |
| WPStaging\Framework\Controller\Default | Default | Niedozwolone, „Default” to zarezerwowane słowo kluczowe |
| WPStaging\Framework\Objects\Manager | Manager | Samo „Manager” jest zbyt nieostre |
Poprawne nazewnictwo namespace’ów i klas:
| W pełni kwalifikowana nazwa klasy | Nazwa niekwalifikowana | Uwagi |
|---|---|---|
| WPStaging\Framework\Util\FileSystem | FileSystem | To FileSystem |
| WPStaging\Framework\Cache\Backend\FileBackend | FileBackend | File Backend |
| WPStaging\Framework\Session\SessionInterface | SessionInterface | Interfejs sesji |
| WPStaging\Framework\StandardController | StandardController | Standardowy kontroler |
| WPStaging\Framework\ObjectManager | ObjectManager |
Przypadki graniczne w nazewnictwie namespace’ów i klas:
| W pełni kwalifikowana nazwa klasy | Nazwa niekwalifikowana | Uwagi |
|---|---|---|
| WPStaging\Framework\Mvc\ControllerInterface | ControllerInterface | Interfejs należy więc do wszystkich kontrolerów w sub-namespace Controller |
| WPStaging\Framework\Mvc\Controller\ControllerInterface | Lepiej | |
| WPStaging\Framework\Cache\AbstractBackend | AbstractBackend | To samo tutaj: w rzeczywistości ta klasa należy do backendów |
| WPStaging\Framework\Cache\Backend\AbstractBackend | Lepiej |
Metody
Nazwy metod powinny jasno opisywać, co robią, więc powinny zaczynać się od czasownika, np. doSomething, makeSomething, isSomething, hasSomething.
Wszystkie nazwy metod zapisuj w lowerCamelCase. Aby uniknąć problemów z różnymi systemami plików, dozwolone są wyłącznie znaki a-z, A-Z i 0-9 — nie używaj znaków specjalnych.
Nazwy metod niech będą opisowe, ale jednocześnie zwięzłe. Konstruktory muszą zawsze nazywać się __construct() — nigdy nie używaj nazwy klasy jako nazwy metody.
myMethod()
someNiceMethodName()
betterWriteLongMethodNamesThanNamesNobodyUnderstands()
singYmcaLoudly()
__construct()
Właściwości i zmienne
Zmienna powinna być rzeczownikiem lub przymiotnikiem, nigdy czasownikiem. Coś przechowuje i powinna wyjaśniać, co zawiera.
Nie używaj słowa kluczowego getSomething dla właściwości. get jest zarezerwowane dla getterów i setterów oraz metod, które wykonują wyraźne działanie i dla których nie ma lepszego słowa kluczowego niż get.
Nazwy zmiennych zapisuje się w lowerCamelCase i powinny być:
- Samowyjaśniające.
- Nieskracane do nierozpoznawalności — raczej dłuższe, jeśli to ułatwia zrozumienie znaczenia.
Poniższy przykład pokazuje dwie zmienne o tym samym znaczeniu, lecz różnym nazewnictwie. Zgodzisz się, że dłuższe wersje są lepsze (prawda…?).
Dobre nazewnictwo zmiennych
$singletonObjectsRegistry
$argumentsArray
$aLotOfHtmlCode
renderHTMLtoScreen
Złe nazewnictwo zmiennych
$sObjRgstry
$argArr
$cx
Jako szczególny wyjątek możesz używać nazw zmiennych $i, $j i $k dla numerycznych indeksów w pętlach for, jeśli na pierwszy rzut oka jasne jest, co oznaczają. Mimo to nadal warto ich unikać.
i18n, sprintf(), esc_html_* i gettext()
Zawsze najpierw używaj funkcji gettext() i opakuj je w sprintf() dla tłumaczonych ciągów z parametrami.
Źle:
esc_html_e(sprintf('There are %1$d monkeys in the %2$s'), $number, $string), 'text-domain');
Dobrze:
// Correct (multi-line): sprintf( /* translators: number of monkeys, location. */ __( 'There are %1$d monkeys in the %2$s', 'text-domain' ), (int) $number, esc_html( $string ) ); // Correct (single-line): /* translators: number of monkeys, location. */ printf( __( 'There are %1$d monkeys in the %2$s', 'text-domain' ), intval( $number ), esc_html( $string ) );
Jeśli używasz printf lub sprintf, wokół ciągu obowiązkowe są pojedyncze cudzysłowy (’), ponieważ podwójne („) powodują, że PHP interpretuje $s jako zmienną s, czego nie chcemy.
Aby zachować zgodność z narzędziem tłumaczeń wporg, musi się tam znaleźć placeholder dla tłumacza.
/* translators: %s: name */
sprintf(esc_html__('string %s to translate', 'text-domain'), esc_html($string));
/* translators: %1$s = name1, %2$s = name2 */
sprintf(esc_html__('string %1$s to translate for %2$s', 'text-domain'), esc_html($string1), esc_html($string2));
Czytaj więcej: https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/#variables
Warunki if-else
Unikaj warunków inline, jeśli wymagają dodatkowych nawiasów i instrukcji if-else lub mają więcej niż kilka stanów do porównania.
W innych przypadkach możesz pisać je inline lub jako osobne wczesne returny.
Źle:
return ((!$this->isWindowsOs() && is_executable($fileName))) && is_writable($fileName) || ($this->isWindowsOs()) && is_writable($fileName);
Dobrze:
if (!$this->isWindowsOs && is_executeable && is_writeable()) {
return true;
}
if ($this->isWindowsOs && is_writeable()) {
return true;
}
return false;
Akcje i filtry
- Używaj stałej do deklaracji nazwy filtra; nazwa stałej powinna mieć wzorzec
FILTER_*. - Zawsze zaczynaj nazwę filtra od
wpstg, stosuj namespace’owanie kropkami, np.wpstg.backups.listing_table, gdzielisting_tableto nazwa metody, w której ta akcja jest używana.
Na przykład:
// Declare const for filter const FILTER_CLONING_UPDATE_ACTIVE_PLUGINS_FILTER = 'wpstg.cloning.update.active_plugins'
a następnie
apply_filters(self::CLONING_UPDATE_ACTIVE_PLUGINS_FILTER, $activePlugins);
Przechowywanie danych w wp_options
- Używaj stałej do deklaracji nazwy opcji; nazwa stałej powinna mieć wzorzec
OPTION_*. - Zawsze zaczynaj nazwę opcji w tabeli od
wpstg, oddzielaj słowa podkreśleniami, np.wpstg_backup_database_settings. Nie zapomnij dodać nowo dodanej opcji do uninstall.php.
Źle:
/**
* The option that stores the staging sites
*/
const STAGING_SITES_OPTION = 'wpstg_staging_sites';
Dobrze:
/**
* The option that stores the staging sites
*/
const OPTION_STAGING_SITES = 'wpstg_staging_sites';
Używanie WPStaging*\FileObject zamiast SplFileObject
- Używaj WPStaging\Framework\Filesystem\FileObject zamiast SplFileObject dla spójnego zachowania
seek()ifgets()we wszystkich wersjach PHP do 8.0.1. - Używaj
readAndMoveNext()zamiastfgets()pofseek()dla spójnego zachowania we wszystkich wersjach PHP do PHP 8.0.1.
Praca ze ścieżkami
- Zawsze używaj jednej z istniejących stałych, np.
WPSTG_PLUGIN_DIRlubWPSTG_PLUGIN_URLprzy pracy ze ścieżkami. - Zawsze używaj forward slasha (/), nigdy
DIRECTORY_SEPARATOR. Forward slash jest kompatybilny z Linuksem i Windowsem, a backward slash (\) działa tylko na Windowsie. Zmniejsza to złożoność, ułatwia czytanie kodu i zapobiega nieoczekiwanym problemom w mieszanych środowiskach hostingowych oraz przy migracji danych z Linuksa na Windows i odwrotnie, jak również przy operacjach na ścieżkach typu search and replace. - Używaj funkcji wp_normalize_path, gdy trzeba zamienić backward slash (\) na forward slash (/).