As part of a refactor on our code base, we have been looking into our use of Yii 2's aliases and PHP's getenv function. Here's a code example:


<link rel="icon" sizes="96x96" type="image/png" href="{{ alias("@interfaceAssetsBaseUrl/img/icons/favicon-96x96.png") }}" />


<link rel="icon" sizes="96x96" type="image/png" href="{{ getenv('INTERFACE_ASSETS_BASE_URL') ~ 'img/icons/favicon-96x96.png' }}"/>

For context, Interface Assets Base URL is set according to your environment; if you're on Dev it will point to your local files. If you're in Staging or Production it'll point to Amazon S3.

My question:

Is there any benefits in terms or performance in using either one of these methods? Does Craft cache one of these, for example?


Performance? Doubtful there is a significant difference, compared to the cost of, say, a database query. It all boils down to accessing arrays, and the number of function calls or string manipulations that it takes to get there is probably not worth worrying about.

The way I see it is that ENV vars are for configuration, and aliases are for convenience / maintainability / legibility of your application's code.

Your example approaches a good explanation for that separation. If you wanted an Environment variable to determine something like an asset volume base URL, I'd recommend this implementation:

1) Create your environment key and value.


2) Create an alias, like @interfaceAssetsBaseUrl that consumes the ENV var:

<?php return [
  // Maybe a multi-env config?
  // ...
  'aliases' => [
    '@interfaceAssetsBaseUrl' => getenv('INTERFACE_ASSETS_BASE_URL')
  // ...

3) Use the alias in your volume configuration via the CP's auto-complete feature, i.e. @interfaceAssetsBaseUrl/icons

👆 I recommend this, mostly because of the nature of Alias parsing vs. manual string concatenation—the alias function is designed to be used as a substitution, and for the substitution to happen properly, irrespective of configuration. Say your ENV key changes, or you want to override it for a particular environment, or (like me) you forget to populate a variable in a new environment? This strikes me as something you shouldn't have to sweat in the template, but rather let the system take care of when it boots up.

There's an additional benefit of relying on aliases as early as possible, which is recursive evaluation. Here's a config snippet from a real project, which is used to defined a number of (local) asset volumes:

'aliases' => [
  '@shared' => getenv('SHARED_PATH'),
  '@private' => '@shared/private',
  '@fonts' => '@private/fonts'

(This app uses an atomic deployment strategy, so the path to those files changes regularly, but SHARED_PATH is a reliable symlink.)

  • Thanks so much! I wasn't expecting such a detailed answer! đź‘Ź
    – Jamie Wade
    Sep 21 '19 at 8:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.