Nie zalecane jest korzystanie z metod statycznych w kodzie, używanie takich metod musi mieć swój powód !
Wyjątki:
<?php
class HtmlHelper
{
public static function a($url, $text): string
{
return sprintf('<a href="%s">%s</a>', $url, $text);
}
}
HtmlHelper::a('https://done.pl', 'Done');
Jeżeli tworzymy helper który zawiera bardzo proste funkcjonalności (nie korzysta z zewnętrznych baz, api itd),
to funkcjonalność powiązana jest z klasą "helper" bardziej jako spójne miejsce w którym wrzucamy funkcjonalność wokół np HTML.
Taki helper powinien być wywoływany wyłącznie na widoku/ w kontrolerze ale nigdy w naszej logice
(proste przetwarzanie danych powinno być na wejściu lub na wyjściu)
np mechanizm do tłumaczeń, tworzenia html, operacji na stringach, formatowanie ciągu znaków
<?php
class Prostokat
{
private $a;
private $b;
public static function factoryKwadrat($a): self
{
return new Prostokat($a, $a);
}
public function __construct($a, $b)
{
$this->a = $a;
$this->b = $a;
}
public function obwod(): float
{
//...
}
}
W innych językach możemy mieć więcej niż jeden konstruktor w php ten patent można uzyskać stosując "factory method"
Dodatkowo nazwa fabryki może nam coś mówić o tym jaki obiekt utworzymy np Prostokat::factoryKwadrat(5);
utworzy nam prostokąt o właściwościach kwadratu, inne przykłady to np
"Dopuszczalne" jest również skorzystanie z przykładu gdzie np obiekt tworzony bedzie korzystał z danych które może nie mogą być prosto wstrzyknięte np
<?php
class Prostokat
{
private $a;
private $b;
public static function factoryYiiParams(): self
{
return new Prostokat(
Yii::$app->params['globalA'],
Yii::$app->params['globalB']
);
}
public static function factorySession(): self
{
return new Prostokat(
Yii::$app->session->get('globalA'),
Yii::$app->session->get('globalB')
);
}
public function __construct($a, $b)
{
$this->a = $a;
$this->b = $a;
}
//...
}
Mamy tu możliwość skorzystania np z mechanizmów yii ale to, że utworzymy obiekt z danych z params lub sesji nie wpływa na to ze klasę
można utworzyć bez tych mechanizmów, np gdy chcemy przetestować klasę a nie chcemy stawiać yii do tego
w Yii często korzysta się z aplikacji za pomocą np Yii::$app->session->get('globalA')
o ile nie jest to jakąś tragiczną praktyka w kontrolerach to jest sposób aby zrobić to lepiej
Trzeba skorzystac z mechanizmu DI (Dependency Injection) i tak w bootstrap aplikacji trzeba ustawić mapowanie klas
bootstrap:
<?php
Yii::$container->set(\yii\web\Application::class, function () {
return Yii::$app;
});
kontroller:
<?php
use yii\web\Application;
class PrzykladController extends Controller
{
/**
* @var Application
*/
private $app;
public function __construct(string $id, Module $module, Application $app, array $config = [])
{
parent::__construct($id, $module, $config);
$this->app = $app;
}
//...
}
W całym kontrolerze możemy używać $this->app
co jest równoznaczne z korzystaniem Yii::$app
, ale tym razem nie robimy tego za pomocą statica. Przydatność tego podejścia bardziej docenić mogą osoby które próbują to jakoś przetestować ale nie chcą stawiać aplikacji.