Creating an application #5 - customizing application parameters

Customizing application parameters

This ApplicationParameters.php allows you to globally configure some important parameters of your application, such as name and charset, you could also add any parameter you need.

The parameters are defined in the file config/params.php and are available in the config files
$params[parameter]. For example, if you want to add a parameter called email, you can do it like this:

<?php
    
declare(strict_types=1);
    
return [
    'app' => [
        'email' => 'admin@example.com',
    ],
];

Add the method email() and getEmail() to the ApplicationParameters::class:

<?php
    
declare(strict_types=1);
    
namespace App;
    
final class ApplicationParameters
{
    private string $charset = 'UTF-8';
    private string $email = '';
    private string $name = 'My Project';
    
    public function charset(string $value): self
    {
        $new = clone $this;
        $new->charset = $value;

        return $new;
    }
    
    public function email(string $value): self
    {
        $new = clone $this;
        $new->adminEmail = $value;

        return $new;
    }
   
    public function getCharset(): string
    {
        return $this->charset;
    }

    public function getEmail(): string
    {
        return $this->adminEmail;
    }

    public function getName(): string
    {
        return $this->name;
    }
    
    public function name(string $value): self
    {
        $new = clone $this;
        $new->name = $value;

        return $new;
    }
}

In your config config/common/application-parameters.php:

<?php
    
declare(strict_types=1);
    
use App\ApplicationParameters;
    
/** @var array $params */
    
return [
    ApplicationParameters::class => [
        'class' => ApplicationParameters::class,
        'charset()' => [$params['app']['charset']],
        'name()' => [$params['app']['name']],
        'email()' => [$params['app']['email']],
    ],
];

You can then access this parameter in your controllers or actions like this:

<?php
    
declare(strict_types=1);
    
namespace App\Action;
    
use App\AplicationParameters;
    
final class MyAction
{
    public function index(ApplicationParameters $applicationParameters): ResponseInterface
    {
        $email = $applicationParameters->getEmail();
        // ...
    }
}

Automatically the container resolves the dependency and accesses the parameter.

2 Likes

Hi terabytesoftw and thank you for the articles.

I decided to write you, since I’m a bit disappointed and confused - are these “posts” on forum supposed to be a replacement for the proper documentation?

Many years ago, when I read the Yii2 documentation, I was far less experienced and the docs were like guide to me to the new world of frameworks and better programming. It literally taught me be a better programmer by explaining why is this thing done that way and why is convenient to do things this way.

But when I’m reading the posts about Yii3 on the forum I’m just confused from everything. There is a lot of new stuff and approaches (which isn’t anything bad) but almost nothing is properly explained. It’s more like cooking receipt. Do this, then this and don’t ask anything. (That’s why I hate food cookboks – they don’t teach you cook, they just blindly tell you what to do without a reasons. Someone should finally make a cookbook for programmers :blush:) But if I wanna use the FW in any scenario, I need to understand why are things the way they are and how they work.

For example, take this post about parameters. In Yii2, having app parameters like app name or charset was extremely clear and easy – there were filles with configs, they were merged together and accessed by Yii::$app->parameters[]. That’s it. I know that in Yii3 we can’t access components this way, but in the post, you are describing a lot of new things and explain nothing. Like literally nothing.

  • Why is there still the config file with the parameters and then a special class, where I have to repeat all to parameters?
  • What’s the point of having ApplicationParameters class?
  • Why I have to add two methods for every parameter?
  • Why are the methods made exactly this way they are?
  • It seems like a lot of repeating work (copypaste method code for every params? What the heck…) – why isn’t it automated/abstracted somehow?
  • What’s the diff between email() and getEmail() and when should I use what method?
  • What’s the purpose of application-parameters.php and why is the array the way it is? The
    Creating an application #2 unfortunately wasn’t the best starting point
  • What exactly the sentence “Automatically the container resolves the dependency and accesses the parameter.“ does mean? The code above looks like a magic to me. If you are pointing to some topic you wrote about earlier, why don’t you link it?

I believe all this code has a good reasons why it’s made this way and that you guys designed it with much higher knowledge then I have, but from my current point of you, it looks like bloody complicated code for adding just one parameter. It looks ridiculous. So if we are supposed to do this way, the brain must now why, what’s the reason, the benefit. And I wanna understand it, I wanna do this way since I believe your approach is good. But I can’t see it in the post. It’s just bunch of very simple instruction “do this, do that”.

Maybe others more experienced with Yii3 understand it better, but maybe there are other people like me who would like to start with Yii3 but struggling with the “entry barrier”. And honestly this posts doesn’t break the barrier a lot.

Also – I’m not a native English speaker, but usually I’m more then okay reading any technical stuff, but these posts feel kind of strange to me. Sometimes it’s hard to understand what was the point of a sentence etc. (I know my writing is much worse :blush: )

So my question is – will there be a proper documentation in Yii2 docs quality and format with explaining theory and good examples?

Or am I just stupid and should get this post right away? :blush:

Thank you guys for your work. I used to use Yii1 for few projects and since then I’ve been working with Yii2 and I love it. Over the years I dug deeper and deeper and understand it more and more to the point I used almost every detail mentioned in the docs. It was satisfying to apply the theory from docs to real world problems, optimizing the code, performance, structure…

But now I’m trying to move on, looking a bit for Symfony and Laravel (their docs are actually great so far – you can feel how hard they try to make you understand them) but also still waiting to Yii3 a long time. But at least for me, these posts don’t help me to get into Yii3.

2 Likes

Thanks for the feedback, basically the biggest change from Yii2 to Yii3, is to change the service locator to a container-di PSR, there are several ways to add parameters, and in the app template one of them is to use a class, in this case AplicationParameters::class, when we do it this way, we must define setter and getter explicitly, which do not allow us to correctly type the parameters, of course, you could also define an array in config/params.php, and use it as in Yii2, the advantage of Yii3 is that i can do it in multiple ways, with respect to the posts, i have written, the truth is i try to convey the information in a very concise way, since long posts tend to be complex and less readable, please you can ask the questions you want, i will gladly try to clarify each one of them, remember in Yii3 there is no yii::$app.

I’m going to make a post about how it would be, add parameters, just like in Yii2.

Of course Yii3 will have documentation like Yii2.

Regards.

2 Likes

Like a @OndrejVasicek.cz I’m veteran of Yii2 and for me begining in Yii3 was hard.
After few questions on Telegram support channel, reading docs from packages, first drafts of guide, this @terabytesoftw posts and reading code of demo or app aplicaiton I understand more - but still not enought :slight_smile:
So waiting for full guide and more @terabytesoftw post here - maybe is’t not fully decriptive, but it’s good base to understand how everyting works. One example is worth more than 1000 words :slight_smile:

1 Like

Parameters service style Yii2:

This ParameterService::class allows you to globally configure some important parameters of your application, such as name and charset, you could also add any parameter you need.

file: src/Service/ParameterService.php

<?php

declare(strict_types=1);

namespace App\Service;

use Yiisoft\Arrays\ArrayHelper;

final class ParameterService
{
    public function __construct(private array $parameters)
    {
    }

    /**
     * Returns a parameter defined in params.
     *
     * @param string $key The key of the parameter to return.
     * @param mixed $default The default value to return if the parameter does not exist.
     *
     * @return mixed
     */
    public function get(string $key, mixed $default = null): mixed
    {
        return ArrayHelper::getValueByPath($this->parameters, $key, $default);
    }
}

The parameters are defined in the file config/parameters.php and avaible in controllers, actions, in the view component as a dependency.

file: config/parameters.php

<?php
    
declare(strict_types=1);
    
return [
    'app' => [
        'email' => 'admin@example.com',
    ],
];

In your config/common/parameter-services.php, you can define the parameters as a service.

<?php

declare(strict_types=1);

use App\Service\ParameterService;

/** @var \Yiisoft\Config\Config $config */

return [
    ParameterService::class => [
        'class' => ParameterService::class,
        '__construct()' => [
            $config->get('parameters'),
        ],
    ]
];

You can then access this parameter in your controllers or actions like this:

<?php
    
declare(strict_types=1);
    
namespace App\Action;
    
use App\Service\ParameterService;
    
final class MyAction
{
    public function index(ParameterService $parameterService): ResponseInterface
    {
        $email = $parameterService->get('app.email');
        // ...
    }
}

Automatically the container resolves the dependency and accesses the parameters.

Now we are going to configure the parameters in the view component, for this we will add the following code to the file config/params.php.

file: config/params.php

<?php

declare(strict_types=1);

use App\Service\ParameterService;
use Yiisoft\Definitions\Reference;

return [
    'yiisoft/view' => [
        'parameters' => [
            'parameterService' => Reference::to(ParameterService::class),
        ],
    ],
];

Now we can access the parameters in the views.

<?php

declare(strict_types=1);

use Yiisoft\View\WebView;

/**
 * @var App\Service\ParameterService $parameterService
 * @var string $content
 */

$this->setTitle($parameterService->get('app.name'));
2 Likes