Se vuoi partecipare allo sviluppo di WP Staging, prendi familiarità con le seguenti linee guida di programmazione e best practice.
- Usa PSR https://www.php-fig.org/psr/.
- Usa la sintassi short Array [].
- Usa camelCase per i nomi delle variabili.
- Usa StudlyCaps per i nomi delle classi.
- Usa gli underscore nei nomi di file e cartelle.
- Evita le condizioni inline.
- Usa le abbreviazioni raramente! Non usare alcuna abbreviazione che non sia stata approvata dal team e non inventare le tue abbreviazioni che non sono comunemente popolari quando nomini proprietà o metodi.
- I nomi per classi, metodi e proprietà dovrebbero spiegare esattamente il loro scopo.
Clean Code
- Il costo totale di possedere un disordine si accumula nel tempo.
- È molto difficile ricostruire un sistema legacy da zero. Il refactoring e i miglioramenti incrementali sono spesso il percorso migliore da seguire.
- In basi di codice disordinate ci possono volere giorni o settimane per completare attività che dovrebbero richiedere solo ore.
- Prenditi il tempo per andare veloce.
- Il clean code fa una cosa bene. Il codice cattivo cerca di fare troppo.
- Il clean code è ben testato.
- Quando leggi codice ben scritto, ogni funzione fa più o meno quello che ti aspettavi.
- Se non sei d’accordo con un principio che qualcuno con decenni di esperienza sta insegnando, faresti bene almeno a considerare il loro punto di vista prima di scartarlo.
- Il codice viene letto molto più spesso di quanto venga scritto.
- Il codice più facile da leggere è più facile da modificare.
- Lascia la base di codice migliore di come l’hai trovata (La regola del Boy Scout).
Commenti e docBlock
- I commenti possono mentire. Possono essere sbagliati fin dall’inizio, o possono essere originariamente accurati e poi diventare obsoleti nel tempo man mano che il codice correlato cambia. Ad es. se rinomini o rifattorizzi un metodo, devi sempre verificare se il commento è ancora valido.
- Usa i commenti per descrivere perché qualcosa è scritto in quel modo, non per spiegare cosa sta accadendo.
- I commenti possono spesso essere evitati usando variabili chiaramente nominate ed estraendo sezioni di codice in funzioni chiaramente nominate.
- Prefissa i tuoi commenti TODO in modo coerente per rendere più facile la loro ricerca. Rivedi e pulisci periodicamente i tuoi commenti TODO.
- Non usare i docBlock solo per il gusto di usarli. I commenti che descrivono cosa fa un metodo, quali argomenti prende e cosa restituisce sono spesso ridondanti nel migliore dei casi e fuorvianti nel peggiore.
- I commenti dovrebbero includere tutte le informazioni e il contesto rilevanti che chi legge il commento avrà bisogno. Non essere pigro o vago quando scrivi un commento.
- I commenti journal e i commenti file author non sono necessari grazie al version control e a git blame.
- Non commentare il codice morto. Eliminalo e basta. Se pensi che ti servirà il codice in futuro, è proprio per questo che esiste il version control.
- Commenta tanto quanto necessario, ma il meno possibile. Se scrivi il tuo metodo e hai la forte pressione di scrivere un commento per esso, il più delle volte il nome del tuo metodo non è abbastanza chiaro o il codice fa più di una cosa. In tal caso, considera un refactoring prima di scrivere un commento.
Code Style
Spazi degli operatori binari
Gli operatori binari ‘=’ e ‘=>’ dovrebbero essere circondati da spazi. C’è un’opzione di formattazione automatica nelle impostazioni di stile del codice dell’IDE che ti permette di allineare l’assegnazione di valori chiave in questo modo:
$array = [
$var => 'foo',
$varvar => 'foo'
];
$var = 1;
$var100 = 100;
$var2000 = 2000;
Questo è un trucco utile per rendere più leggibili porzioni più grandi di codice simile.
Condizioni Yoda
Abbiamo votato di non usare le condizioni Yoda per facilità di lettura.
Non consigliato:
if ( true === $var ) {}
Consigliato:
if ( $var === true ) {}
Invocazione native function/constant
L’invocazione native è una tecnica per aggiungere una backward slash (\) all’inizio dell’invocazione di function/constant per velocizzare la risoluzione. In questo modo PHP non ha bisogno di controllare se la function/constant è dal namespace o native.
Abbiamo votato di non usare la tecnica Native function/constant invocation per facilità di lettura ed evitare errori sulla nostra base di codice.
Ma in alcuni casi, è permesso usarla con attenzione e saggezza.
Non consigliato:
if ( \is_array($var) ) {}
if ( \PHP_SAPI === 'cli') {}
Consigliato:
if ( is_array($var) ) {}
if ( PHP_SAPI === 'cli') {}
Namespace e nomi delle classi
Secondo i principi della Object-Oriented Programming (OOP), i nomi delle classi dovrebbero essere sostantivi, in quanto rappresentano oggetti o concetti nel sistema. Questo aiuta a rendere il codice più leggibile e comprensibile per gli altri sviluppatori.
Tuttavia, vale la pena notare che alcuni linguaggi di programmazione, incluso PHP, permettono ai verbi di essere usati come nomi di classi. In questi casi, il verbo viene solitamente usato come modo per indicare che la classe rappresenta un’azione o un comportamento piuttosto che un oggetto.
Ad esempio, una classe chiamata “Mailer” potrebbe rappresentare un oggetto che invia email, mentre una classe chiamata “SendMail” potrebbe rappresentare un comportamento che invia email. Mentre l’uso di verbi come nomi di classi è tecnicamente consentito, può rendere il codice più difficile da leggere e capire, ed è generalmente sconsigliato a favore dell’uso di sostantivi.
- Solo i caratteri a-z, A-Z e 0-9 sono permessi per i nomi di namespace e classe.
- I namespace sono solitamente scritti in UpperCamelCase ma sono permesse variazioni per nomi e abbreviazioni ben consolidati.
- I nomi delle classi sono sempre scritti in
UpperCamelCase. - Il nome della classe non qualificato deve essere inteso letteralmente anche senza il namespace.
- Lo scopo principale dei namespace è la categorizzazione e l’ordinamento
- I nomi delle classi devono essere sostantivi, mai aggettivi.
- Il nome delle classi astratte deve iniziare con la parola “Abstract”, i nomi delle classi di aspect devono terminare con la parola “Aspect”.
Naming non corretto di namespace e classi:
| Nome classe completamente qualificato | Nome non qualificato | Note |
|---|---|---|
| WPStaging\Framework\Session\Php | Php | La classe non è una rappresentazione di PHP |
| WPStaging\Framework\Cache\Backend\File | File | La classe non rappresenta un file! |
| WPStaging\Framework\Session\Interface | Interface | Non permesso, “Interface” è una parola chiave riservata |
| WPStaging\Framework\Controller\Default | Default | Non permesso, “Default” è una parola chiave riservata |
| WPStaging\Framework\Objects\Manager | Manager | Solo “Manager” è troppo vago |
Naming corretto di namespace e classi:
| Nome classe completamente qualificato | Nome non qualificato | Note |
|---|---|---|
| WPStaging\Framework\Util\FileSystem | FileSystem | Questo è il FileSystem |
| WPStaging\Framework\Cache\Backend\FileBackend | FileBackend | Un File Backend |
| WPStaging\Framework\Session\SessionInterface | SessionInterface | Interfaccia per una sessione |
| WPStaging\Framework\StandardController | StandardController | Il controller standard |
| WPStaging\Framework\ObjectManager | ObjectManager |
Casi limite nel naming di namespace e classi:
| Nome classe completamente qualificato | Nome non qualificato | Note |
|---|---|---|
| WPStaging\Framework\Mvc\ControllerInterface | ControllerInterface | Di conseguenza, l’interfaccia appartiene a tutti i controller nel sub namespace Controller |
| WPStaging\Framework\Mvc\Controller\ControllerInterface | Meglio | |
| WPStaging\Framework\Cache\AbstractBackend | AbstractBackend | Lo stesso qui: in realtà questa classe appartiene ai backend |
| WPStaging\Framework\Cache\Backend\AbstractBackend | Meglio |
Metodi
I nomi dei metodi dovrebbero descrivere chiaramente cosa fa quindi dovrebbero iniziare con un verbo come doSomething, makeSomething, isSomething, hasSomething.
Tutti i nomi dei metodi sono scritti in lowerCamelCase. Per evitare problemi con i diversi filesystem, solo i caratteri a-z, A-Z e 0-9 sono permessi per i nomi dei metodi – non usare caratteri speciali.
Rendi i nomi dei metodi descrittivi, ma mantienili concisi allo stesso tempo. I costruttori devono essere sempre chiamati __construct(), non usare mai il nome della classe come nome del metodo.
myMethod()
someNiceMethodName()
betterWriteLongMethodNamesThanNamesNobodyUnderstands()
singYmcaLoudly()
__construct()
Proprietà e variabili
Una variabile dovrebbe essere un sostantivo o un aggettivo e mai un verbo. Memorizza qualcosa e dovrebbe spiegare cosa contiene.
Non usare la parola chiave getSomething per una proprietà. Il get è riservato per i getter e setter e per i metodi che fanno esplicitamente qualcosa e dove non c’è parola chiave migliore di get.
I nomi delle variabili sono scritti in lowerCamelCase e dovrebbero essere:
- Autoesplicativi.
- Non abbreviati oltre il riconoscimento, ma piuttosto più lunghi se rende il loro significato più chiaro.
L’esempio seguente mostra due variabili con lo stesso significato ma con naming diverso. Sicuramente sarai d’accordo che le versioni più lunghe sono migliori (vero?).
Buon naming delle variabili
$singletonObjectsRegistry
$argumentsArray
$aLotOfHtmlCode
renderHTMLtoScreen
Cattivo naming delle variabili
$sObjRgstry
$argArr
$cx
Come eccezione speciale puoi usare nomi di variabili come $i, $j e $k per indici numerici nei loop for se è chiaro cosa significano a prima vista. Ma anche allora dovresti evitarli.
i18n, sprintf(), esc_html_* e gettext()
Usa sempre le funzioni gettext() per prime e avvolgile dentro sprintf() quando ci sono parametri in una stringa traducibile.
Sbagliato:
esc_html_e(sprintf('There are %1$d monkeys in the %2$s'), $number, $string), 'text-domain');
Corretto:
// 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 ) );
Se usi printf o sprintf, le virgolette singole (‘) intorno alla stringa sono obbligatorie perché le virgolette doppie (“) diranno a PHP di interpretare $s come variabile s, il che non è quello che vogliamo.
Per standardizzare con lo strumento di traduzione wporg, deve includere un placeholder per il traduttore.
/* 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));
Leggi di più: https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/#variables
Condizioni If Else
Evita le condizioni inline se richiedono parentesi extra e statement if else o hanno più di multipli stati da confrontare.
Altrimenti va bene scriverle inline o in condizioni di early return separate.
Cattivo:
return ((!$this->isWindowsOs() && is_executable($fileName))) && is_writable($fileName) || ($this->isWindowsOs()) && is_writable($fileName);
Buono:
if (!$this->isWindowsOs && is_executeable && is_writeable()) {
return true;
}
if ($this->isWindowsOs && is_writeable()) {
return true;
}
return false;
Action e Filter
- Usa una costante per dichiarare il nome del filter, il nome della costante dovrebbe rispettare il pattern
FILTER_*. - Inizia sempre il nome di un filter con
wpstg, fai un po’ di namespacing con i punti comewpstg.backups.listing_tabledovelisting_tableè il nome del metodo dove viene usata quell’action.
Ad esempio:
// Declare const for filter const FILTER_CLONING_UPDATE_ACTIVE_PLUGINS_FILTER = 'wpstg.cloning.update.active_plugins'
e poi
apply_filters(self::CLONING_UPDATE_ACTIVE_PLUGINS_FILTER, $activePlugins);
Memorizzare dati in wp_options
- Usa una costante per dichiarare il nome dell’option, il nome della costante dovrebbe rispettare il pattern
OPTION_*. - Inizia sempre il nome di un’option della tabella con
wpstg, separa le parole con underscore comewpstg_backup_database_settings. Non dimenticare di aggiungere l’option appena aggiunta in uninstall.php
Cattivo:
/**
* The option that stores the staging sites
*/
const STAGING_SITES_OPTION = 'wpstg_staging_sites';
Buono:
/**
* The option that stores the staging sites
*/
const OPTION_STAGING_SITES = 'wpstg_staging_sites';
Usare WPStaging*\FileObject invece di SplFileObject
- Usa WPStaging\Framework\Filesystem\FileObject invece di SplFileObject per un comportamento coerente di
seek()efgets()su tutte le versioni PHP fino a 8.0.1. - Usa
readAndMoveNext()invece difgets()dopofseek()per un comportamento coerente su tutte le versioni PHP fino a PHP 8.0.1.
Gestione dei percorsi
- Usa sempre una delle costanti esistenti come
WPSTG_PLUGIN_DIRoWPSTG_PLUGIN_URLquando lavori con i percorsi. - Usa sempre la forward slash (/) e mai
DIRECTORY_SEPARATOR. La forward slash è compatibile con Linux e Windows, mentre la backward slash (\) funziona solo su Windows. Questo ridurrà la complessità, renderà il codice più facile da leggere e preverrà problemi inaspettati su ambienti host misti o quando si migrano i dati da Linux a Windows o viceversa o si fa il processing sui percorsi come fare un cerca e sostituisci di percorsi. - Usa la funzione wp_normalize_path quando necessario per sostituire una backward slash (\) con una forward slash (/).