docs/internals-pl/core-code-style.md
Poniższy styl kodowania jest stosowany w kodzie frameworka Yii 2.x i oficjalnych rozszerzeniach. Jeśli planujesz wysłać prośbę o dołączenie kodu do bazowego frameworka, powinieneś rozważyć stosowanie takiego samego stylu. Nie zmuszamy jednak nikogo do stosowania go we własnych aplikacjach. Wybierz styl, który najbardziej odpowiada Twoim potrzebom.
Możesz pobrać gotową konfigurację dla CodeSniffera pod adresem: https://github.com/yiisoft/yii2-coding-standards
Używamy przede wszystkim standardu kodowania PSR-2, zatem wszystko, co dotyczy PSR-2 dotyczy również naszego stylu kodowania.
<?php albo <?=.StudlyCaps.camelCase.camelCase.elseif zamiast else if.<?php ?> lub <?=; NIE MOŻE używać innych tagów takich jak <?.?>..php.Kod PHP MUSI używać wyłącznie UTF-8 bez znacznika BOM.
Nazwy klas MUSZĄ być zadeklarowane w formacie StudlyCaps. Przykładowo Controller, Model.
Termin "klasa" odnosi się tutaj do wszystkich klas i interfejsów.
CamelCase./**
* Dokumentacja
*/
class MyClass extends \yii\base\BaseObject implements MyInterface
{
// kod
}
Stałe klasy MUSZĄ być zadeklarowane wyłącznie wielkimi literami z łącznikiem w postaci podkreślnika. Dla przykładu:
<?php
class Foo
{
const VERSION = '1.0';
const DATE_APPROVED = '2012-06-01';
}
public.$_varName.$camelCase z pierwszą literą małą.$i i $j.Przykładowo:
<?php
class Foo
{
public $publicProp1;
public $publicProp2;
protected $protectedProp;
private $_privateProp;
public function someMethod()
{
// ...
}
}
camelCase z pierwszą literą małą.private, protected i public. var nie jest dozwolony./**
* Dokumentacja
*/
class Foo
{
/**
* Dokumentacja
*/
public function bar()
{
// code
return $value;
}
}
@param, @var, @property i @return muszą deklarować użyte typy bool, int, string, array lub null.
Można również używać nazw klas jak Model lub ActiveRecord.ClassName[].isActive, hasClass, itp.) pierwsza linia powinna zaczynać się od Checks whether.@return powinien wyraźnie opisywać co jest zwracane./**
* Checks whether the IP is in subnet range
*
* @param string $ip an IPv4 or IPv6 address
* @param int $cidr the CIDR lendth
* @param string $range subnet in CIDR format e.g. `10.0.0.0/8` or `2001:af::/64`
* @return bool whether the IP is in subnet range
*/
private function inRange($ip, $cidr, $range)
{
// ...
}
__construct zamiast konstruktorów w stylu PHP 4.true, false, null i array.Zmiana typu istniejącej zmiennej jest uznawana za złą praktykę. Należy unikać pisania kodu w ten sposób, chyba że jest to naprawdę konieczne.
public function save(Transaction $transaction, $argument2 = 100)
{
$transaction = new Connection; // źle
$argument2 = 200; // dobrze
}
$str = 'Like this.';
$str1 = "Hello $username!";
$str2 = "Hello {$username}!";
Poniższy zapis jest niedozwolony:
$str3 = "Hello ${username}!";
Należy dodać spacje przed i po kropce podczas łączenia łańcuchów:
$name = 'Yii' . ' Framework';
W przypadku długich łańcuchów format jest następujący:
$sql = "SELECT *"
. "FROM `post` "
. "WHERE `id` = 121 ";
W przypadku tablic używamy krótkiej składni PHP 5.4.
Należy używać następującego formatu podczas deklarowania tablicy:
$arr = [3, 14, 15, 'Yii', 'Framework'];
W przypadku, gdy ilość elementów jest zbyt duża dla pojedynczej linii:
$arr = [
3, 14, 15,
92, 6, $test,
'Yii', 'Framework',
];
Należy używać następującego formatu podczas deklarowania tablicy asocjacyjnej:
$config = [
'name' => 'Yii',
'options' => ['usePHP' => true],
];
if ($event === null) {
return new Event();
}
if ($event instanceof CoolEvent) {
return $event->instance();
}
return null;
// poniższy zapis jest NIEDOZWOLONY:
if (!$model && null === $event)
throw new Exception('test');
Należy unikać stosowania else po return, kiedy ma to sens.
Należy używać guard conditions.
$result = $this->getResult();
if (empty($result)) {
return true;
} else {
// przetwarzanie wyniku
}
wygląda lepiej w postaci
$result = $this->getResult();
if (empty($result)) {
return true;
}
// przetwarzanie wyniku
Należy używać następującego formatu dla instrukcji switch:
switch ($this->phpType) {
case 'string':
$a = (string) $value;
break;
case 'integer':
case 'int':
$a = (int) $value;
break;
case 'boolean':
$a = (bool) $value;
break;
default:
$a = null;
}
doIt(2, 3);
doIt(['a' => 'b']);
doIt('a', [
'a' => 'b',
'c' => 'd',
]);
Należy zwrócić uwagę na spację pomiędzy słowem function/use a otwierającym nawiasem:
// dobrze
$n = 100;
$sum = array_reduce($numbers, function ($r, $x) use ($n) {
$this->doMagic();
$r += $x * $n;
return $r;
});
// źle
$n = 100;
$mul = array_reduce($numbers, function($r, $x) use($n) {
$this->doMagic();
$r *= $x * $n;
return $r;
});
Należy stosować dokumentację zgodnie ze składnią phpDoc.
Kod bez dokumentacji jest niedozwolony.
Każdy plik klasy musi zawierać blok dokumentacji "poziomu pliku" na początku pliku i blok dokumentacji "poziomu klasy" zaraz nad klasą.
Nie ma konieczności używania @return, jeśli metoda niczego nie zwraca.
Wszystkie wirtualne właściwości w klasach, które rozszerzają yii\base\BaseObject są udokumentowane za pomocą tagu @property
w bloku dokumentacji klasy.
Adnotacje te są automatycznie generowane z tagów @return lub @param w odpowiednich getterach lub setterach przez
uruchomienie ./build php-doc w folderze build.
Można dodać tag @property do gettera lub settera, aby wprost określić informację dla dokumentacji właściwości zadeklarowanej
w tych metodach, kiedy opis różni się od tego, co znajduje się w @return. Poniżej znajduje się przykład:
<?php
/**
* Returns the errors for all attribute or a single attribute.
* @param string $attribute attribute name. Use `null` to retrieve errors for all attributes.
* @property array An array of errors for all attributes. Empty array is returned if no error.
* The result is a two-dimensional array. See [[getErrors()]] for detailed description.
* @return array errors for all attributes or the specified attribute. Empty array is returned if no error.
* Note that when returning errors for all attributes, the result is a two-dimensional array, like the following:
* ...
*/
public function getErrors($attribute = null)
<?php
/**
* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
/**
* Component is the base class that provides the *property*, *event* and *behavior* features.
*
* @include @yii/docs/base-Component.md
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Component extends \yii\base\BaseObject
/**
* Returns the list of attached event handlers for an event.
* You may manipulate the returned [[Vector]] object by adding or removing handlers.
* For example,
*
* ```
* $component->getEventHandlers($eventName)->insertAt(0, $eventHandler);
* ```
*
* @param string $name the event name
* @return Vector list of attached event handlers for the event
* @throws Exception if the event is not defined
*/
public function getEventHandlers($name)
{
if (!isset($this->_e[$name])) {
$this->_e[$name] = new Vector;
}
$this->ensureBehaviors();
return $this->_e[$name];
}
Jak widać w powyższych przykładach, używamy składni markdown do formatowania komentarzy phpDoc.
W dokumentacji stosowana jest dodatkowa składnia do linkowania klas, metod i właściwości:
[[canSetProperty]] utworzy link do metody lub właściwości canSetProperty w tej samej klasie.[[Component::canSetProperty]] utworzy link do metody canSetProperty w klasie Component w tej samej przestrzeni nazw.[[yii\base\Component::canSetProperty]] utworzy link do metody canSetProperty w klasie Component w przestrzeni nazw yii\base.[[Component]] utworzy link do klasy Component w tej samej przestrzeni nazw. Można tutaj również dodać przestrzeń nazw.Aby nadać powyższym linkom inną etykietę niż nazwa klasy lub metody, można użyć składni pokazanej w poniższym przykładzie:
... as displayed in the [[header|header cell]].
Część przed | jest linkowaną metodą, właściwością lub klasą, a część po | jest etykietą linku.
Możliwe jest też linkowanie do Przewodnika używając następującej składni:
[link to guide](guide:file-name.md)
[link to guide](guide:file-name.md#subsection)
// a nie od #.=== [] vs empty()Należy używać empty(), kiedy jest to możliwe.
Należy powracać (return) wcześnie, kiedy tylko instrukcje warunkowe zaczynają się zagnieżdżać. Nie ma to znaczenia w przypadku krótkich metod.
self vs. staticNależy zawsze używać static z wyjątkiem poniższych przypadków:
self: self::MY_CONSTANTself: self::$_eventsself do wywołania metod, kiedy ma to sens, jak w przypadku wywołań rekurencyjnych aktualnej implementacji zamiast rozszerzania implementacji klas.Właściwości pozwalające na skonfigurowanie komponentu, tak, aby nie robił czegoś, powinny przyjmować wartość false. null, '' lub [] nie powinny być traktowane w ten sposób.