35

Running Slim 4 in a subdirectory - Rob Allen

 4 years ago
source link: https://www.tuicool.com/articles/BvUB7vu
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

If you want to run Slim 4 in a subdirectory of your website, then you have a few things you need to do. Let’s consider the situation:

  • Your main website is in the directory /var/www/html and is accessed at https://example.com/ .
  • You want your new Slim 4 app to be in the directory /var/www/html/myapp and to be accessed at https://example.com/myapp .
  • Your Slim 4 index.php file is stored in /var/www/html/myapp .

There are two things you need to sort out: the web server and the Slim app. Let’s start with the web server.

The web server (Apache)

I’m going to cover Apache here as that’s the one I know. Somewhere in your virtual host definition file (a .conf file within /etc/apache2/sites-available on Ubuntu) you have DocumentRoot /var/www/html . You should also have a <Directory "/var/www/html"> section. Ensure that there is AllowOverride All within that Directory section so that Apache will read .htaccess files.

Create a .htaccess file in /var/www/html/myapp with the following contents:

RewriteEngine On
RewriteBase /myapp
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]

The key thing here is the RewriteBase directive which must be set to the URL segments where your index.php is. In our case, our Slim 4 app’s index.php is at https://example.com/myapp/index.php , so the RewriteBase is /myapp/ . If our index.php was at https://example.com/foo/bar/index.php , then we would set RewriteBase /foo/bar/ .

Now that we’ve told Apache where to rewrite from, we need to tell Slim 4 too.

Slim 4 config

In our Slim 4 application, we need to set the base path so that the router can match the URL from the browser with the path set in the route registration methods ( $app->get() , $app->post() ). This is done with the setBasePath() method.

In your index.php , add:

$app->setBasePath('/myapp');

Note that you do not include the trailing / as that’s the first character in the route registration method’s path (.e.g $app->get('/contact', ...) ).

Everything will now work, but if you don’t want to hard code the base path in setBasePath() , then you can use this function:

$app->setBasePath((function () {
    $scriptDir = str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME']));
    $uri = (string) parse_url('http://a' . $_SERVER['REQUEST_URI'] ?? '', PHP_URL_PATH);
    if (stripos($uri, $_SERVER['SCRIPT_NAME']) === 0) {
        return $_SERVER['SCRIPT_NAME'];
    }
    if ($scriptDir !== '/' && stripos($uri, $scriptDir) === 0) {
        return $scriptDir;
    }
    return '';
})());

In this case, we define an anonymous function and call it. The code in this anonymous function is based on how Slim 3 determined the base path. It works well when it works, but if you have a more esoteric requirement, then it won’t work. With Slim 3, it was complicated to handle those situations, which is why in Slim 4 it’s an explicit setBasePath() call where you have full control.

All done

There you have it. This is another case where Slim 4 has removed some magic as that magic didn’t work in all situations. The same solution can be used for any web server and will allow you to run your Slim 4 application in subdirectory should you need to.

Update Slim’s website now has documentation on this too.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK