Search code examples
phpapache.htaccesssymlink

Link to another folder when a certain folder is called using an env variable


I've got this code architecture :

  • root
    • locales
    • subdomain1
      • locales
    • subdomain2
      • locales
    • .env

In my .env, I've got an env file called "DOMAIN=XXX". If that variable is not set, /root/locales is used. If it's set DOMAIN=subdomain1, I want the locales file of the subdomain to be used /root/subdomain1/locales.

Knowing that in my env I got DOMAIN=subdomain1, I want PHP to change that path to /root/subdomain1/locales/XXX.

Example :

// In index.php I got 
symlink('/root/locales/XXX', '/root/subdomain1/locales/XXX'); // I get the "subdomain1" from the .env variable

// In other files I've got
require_once('/root/locales/XXX')

I've tried using PHP's symlink function, but it doesn't do anything. Am I using that function properly? Does any of you have other ways of doing this? I can not change the path manually in every require/include cuz I've got thousands.

EDIT : In other files I've got require_once('/root/locales/XXX') that I'm not able to change, that's why I want to create a symlink, to update the path for all the require_once that exists without having to edit each and every one.


Solution

  • You can't have both a file and a symlink with the same name in the same directory, so your call to symlink() can't work.

    A solution would be to change your hierarchy to the following:

    • root
      • main
        • locales
      • subdomain1
        • locales
      • subdomain2
        • locales
      • .env

    When DOMAIN is not defined, create a symlink like this (beware of the parameter order of symlink()):

    symlink('/root/main/locales', '/root/locales');
    

    When DOMAIN is defined, create a symlink like this:

    symlink('/root/'.$_ENV['DOMAIN'].'/locales', '/root/locales');
    

    You can handle both cases at once:

    $domain = $_ENV['DOMAIN'] ?? 'main';
    @unlink('/root/locales');
    symlink("/root/$domain/locales", '/root/locales');
    

    You will find a simple online test here which shows that symlinks actually work.

    Of course, the PHP user will need permission to create a symlink in /root, so it may still fail.

    But do you really need to create it on the fly? Can the .env file suddenly change? If not, then you should just manually create the symlink on the command line.

    Finally, another solution would be to fix your PHP scripts to include the correct file. You said "I cannot change the path manually" because you have many, but nothing prevents you from writing a utility that automatically scans and fixes your scripts. Basically you just need to replace the line:

    require_once('/root/locales/XXX');
    

    with another implementation, so it's a simple search and replace.