1

Yii2 has no problem addressing namespaces outside of the active application directory tree. However I would like to use a require_once statement to get a file holding just constants (i.e., a long list of define(CONSTANT, value) statements) from a location that both the frontend and backend Yii2 advanced template application instances can share.

Right now I am using:

require_once '..\..\common\config\keywords.php';

but this fails when I migrate my application from the Windows development environment in which I am working to the Linux environment where it runs in production, possibly because the relative addressing prefix ('..\..\') isn't something Linux can interpret (?).

Ideally I would like a solution that uses an alias or in some way does not depend on relative or absolute paths. But while this works to include the file when it is located under the base application path:

require_once Yii::$app->basePath.'\config\keywords.php';

.. it still doesn't give me a way to address a directory from a starting point higher than the application base path.

This seems like a common problem that anyone trying to use a shared file of constants would have. How do experts solve it? Am I missing a more elegant approach?

ZorbaTheGeek
  • 155
  • 1
  • 2
  • 8
  • try using the forward slash which works on both linux and windows `/` instead of the backslashes \ Also i'm taking `require once` as a typo in the question. – ArtisticPhoenix May 23 '16 at 03:24
  • I have found that I cannot use forward-slashes (`/`) and back-slashes (`\\``) indiscriminately. See my comment to @arogachev below. Thank you for catching the `require once` typo. It should read `require_once`. I'll fix it in the question if Stack Overflow allows that. – ZorbaTheGeek May 25 '16 at 06:01
  • Maybe you can make a consent or variable for the separator. and switch based on the os. The use with the class `ConstantsSetter::setConstants` is a namespace which needs to be backslash, that's probably some Yii thing they do to identify the namespaces. – ArtisticPhoenix May 26 '16 at 02:54

1 Answers1

1

1) If you want to use directory paths explicitly:

Windows understands both / and \ slashes, while Linux and other OS - /. Keep that in mind when constructing paths. So use / instead.

Sometimes it's more flexible to use special predefined PHP constant DIRECTORY_SEPARATOR. Concatenate it with folder names and you get platform indepedent path.

2) Other option is avoid using paths explicitly. Create component (helper class, for example ConstantsSetter) with method that do all the stuff you need, add namespace to it (for example common\components), then execute it during application bootstrap. You can directly add call to a bootstrap.php file (see this related answer) or use yii\base\BoostrapInterface.

Community
  • 1
  • 1
arogachev
  • 33,150
  • 7
  • 114
  • 117
  • @ZorbaTheGeek Glad to help. Please mark the answer as accepted in this case (you can also upvote it). – arogachev May 25 '16 at 05:51
  • 1
    Option (2) from @arogachev worked perfectly. The only thing I'd add is that with respect to Option (1), the statement I ended up appending to bootstrap.php (`common\helpers\ConstantsSetter::setConstants();`) failed when written as `common/helpers/ConstantsSetter::setConstants();` Does the interchangeability of forward-slashes and back-slashes only apply to strings in quotes? – ZorbaTheGeek May 25 '16 at 05:56
  • @ZorbaTheGeek You should read about [namespaces in PHP](http://php.net/manual/en/language.namespaces.php). – arogachev May 25 '16 at 06:07
  • I love namespaces - they're the bomb! However the php "rule" is that they have to be the first line in the class definition file. bootstrap.php is not a true class definition - it is really a code snippet that yii.php includes with a require statement at the start of the application load. In other words, I don't think they can be used here. Am I missing something? – ZorbaTheGeek May 25 '16 at 06:16
  • @ZorbaTheGeek You can use namespaced classes and their methods in file without namespace. Another solution as I mentioned is using `BootstrapInterface` (there you can define your own namespace). – arogachev May 25 '16 at 06:22
  • This is helpful, and I have just spent some time reading through the php documentation to which you linked above. But I want to be sure that I understand what you are explaining. In the example above, where I am calling the method of a class (ConstantsSetter) in the bootstrap.php file, is the active namespace for the classes in bootstrap.php not "yii" (since Yii.php extends BaseYii.php and baseYii specifies yii as the namespace, which Yii.php does not override)? If I need to go back to the basics just let me know. I use namespaces a lot but my understanding might still be narrow. – ZorbaTheGeek May 25 '16 at 06:53
  • @ZorbaTheGeek Framework classes have `yii\...` namespace, custom can be any you want, for example `common\helpers` is correct. – arogachev May 25 '16 at 07:07
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/112859/discussion-between-zorbathegeek-and-arogachev). – ZorbaTheGeek May 25 '16 at 07:08
  • You can use namespaces outside the context of a class, such as `namespace foo{ function test(){}..... }` then it is `\foo\test()` – ArtisticPhoenix May 26 '16 at 03:00