From 986f010dde2ca80f7de094e446ff947eb54c799a Mon Sep 17 00:00:00 2001 From: David Grudl Date: Wed, 29 Sep 2021 20:03:06 +0200 Subject: [PATCH] readme.md: updated code --- readme.md | 85 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/readme.md b/readme.md index f0c9ad926..49dea9d54 100644 --- a/readme.md +++ b/readme.md @@ -50,8 +50,8 @@ We have the object representing email: ```php class Mail { - public $subject; - public $message; + public string $subject; + public string $message; } ``` @@ -60,7 +60,7 @@ An object which can send emails: ```php interface Mailer { - function send(Mail $mail, $to); + function send(Mail $mail, string $to): void; } ``` @@ -69,7 +69,7 @@ A support for logging: ```php interface Logger { - function log($message); + function log(string $message): void; } ``` @@ -78,23 +78,25 @@ And finally, a class that provides sending newsletters: ```php class NewsletterManager { - private $mailer; - private $logger; + private Mailer $mailer; + private Logger $logger; - function __construct(Mailer $mailer, Logger $logger) + public function __construct(Mailer $mailer, Logger $logger) { $this->mailer = $mailer; $this->logger = $logger; } - function distribute(array $recipients) + public function distribute(array $recipients): void { $mail = new Mail; - ... + $mail->subject = '...'; + $mail->message = '...'; + foreach ($recipients as $recipient) { $this->mailer->send($mail, $recipient); } - $this->logger->log(...); + $this->logger->log('...'); } } ``` @@ -106,7 +108,7 @@ Also, we have a ability to implement own `Logger` or `Mailer`, like this: ```php class SendMailMailer implements Mailer { - function send(Mail $mail, $to) + public function send(Mail $mail, string $to): void { mail($to, $mail->subject, $mail->message); } @@ -114,14 +116,14 @@ class SendMailMailer implements Mailer class FileLogger implements Logger { - private $file; + private string $file; - function __construct($file) + public function __construct(string $file) { $this->file = $file; } - function log($message) + public function log(string $message): void { file_put_contents($this->file, $message . "\n", FILE_APPEND); } @@ -135,26 +137,26 @@ Container for our application might look like this: ```php class Container { - private $logger; - private $mailer; + private ?Logger $logger; + private ?Mailer $mailer; - function getLogger() + public function getLogger(): Logger { - if (!$this->logger) { + if (!isset($this->logger)) { $this->logger = new FileLogger('log.txt'); } return $this->logger; } - function getMailer() + public function getMailer(): Mailer { - if (!$this->mailer) { + if (!isset($this->mailer)) { $this->mailer = new SendMailMailer; } return $this->mailer; } - function createNewsletterManager() + public function createNewsletterManager(): NewsletterManager { return new NewsletterManager($this->getMailer(), $this->getLogger()); } @@ -213,7 +215,7 @@ The container will be generated only once and the code is stored in cache (in di During development it is useful to activate auto-refresh mode which automatically regenerate the container when any class or configuration file is changed. Just in the constructor `ContainerLoader` append `true` as the second argument: ```php -$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp', true); +$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp', autoRebuild: true); ``` @@ -244,9 +246,9 @@ Class of the service: ```php class NewsletterManager { - private $anotherService; + private AnotherService $anotherService; - public function setAnotherService(AnotherService $service) + public function setAnotherService(AnotherService $service): void { $this->anotherService = $service; } @@ -254,7 +256,7 @@ class NewsletterManager ... ``` -We can also add the `inject: yes` directive. This directive will enable automatic call of `inject*` methods and passing dependencies to public variables with `@inject` annotations: +We can also add the `inject: yes` directive. This directive will enable automatic call of `inject*` methods and passing dependencies to public variables with #[Inject] attribute: ```neon services: @@ -266,21 +268,23 @@ services: Dependency `Service1` will be passed by calling the `inject*` method, dependency `Service2` will be assigned to the `$service2` variable: ```php +use Nette\DI\Attributes\Inject; + class FooClass { - private $service1; + private Service1 $service1; // 1) inject* method: - public function injectService1(Service1 $service) + public function injectService1(Service1 $service): void { $this->service1 = $service1; } - // 2) Assign to the variable with the @inject annotation: + // 2) Assign to the variable with the #[Inject] attribute: - /** @inject @var Service2 */ - public $service2; + #[Inject] + public Service2 $service2; } ``` @@ -291,17 +295,14 @@ However, this method is not ideal, because the variable must be declared as publ Factories --------- -We can use factories generated from an interface. The interface must declare the returning type in the `@return` annotation of the method. Nette will generate a proper implementation of the interface. +We can use factories generated from an interface. The interface must declare the returning type of the method. Nette will generate a proper implementation of the interface. The interface must have exactly one method named `create`. Our factory interface could be declared in the following way: ```php -interface IBarFactory +interface BarFactory { - /** - * @return Bar - */ - public function create(); + function create(): Bar; } ``` @@ -310,7 +311,7 @@ The `create` method will instantiate an `Bar` with the following definition: ```php class Bar { - private $logger; + private Logger $logger; public function __construct(Logger $logger) { @@ -323,7 +324,7 @@ The factory will be registered in the `config.neon` file: ```neon services: - - IBarFactory + - BarFactory ``` Nette will check if the declared service is an interface. If yes, it will also generate the corresponding implementation of the factory. The definition can be also written in a more verbose form: @@ -331,7 +332,7 @@ Nette will check if the declared service is an interface. If yes, it will also g ```neon services: barFactory: - implement: IBarFactory + implement: BarFactory ``` This full definition allows us to declare additional configuration of the object using the `arguments` and `setup` sections, similarly as for all other services. @@ -341,14 +342,14 @@ In our code, we only have to obtain the factory instance and call the `create` m ```php class Foo { - private $barFactory; + private BarFactory $barFactory; - function __construct(IBarFactory $barFactory) + function __construct(BarFactory $barFactory) { $this->barFactory = $barFactory; } - function bar() + function bar(): void { $bar = $this->barFactory->create(); }