Slim: Slim 3 cannot work in subdirectory. Cannot work when accessed from localhost/slim_app_dir

Hey Folks 😃

Slim 3 cannot work in subdirectory. Cannot work when accessed from localhost/slim_app_dir. BUT, no problem at all when using virtual host. I really really need to run slim 3 on sub directory.

I create / main route. It;s ok when accessed via virtual host.

$app->get('/', function ($request, $response, $args) {

    if (isset($_SESSION['Auth'])) {
        return $response->withStatus(302)->withHeader('Location', '/dashboard');
    }

    return $this->view->render(
        $response,
        'login/index'
    );
});

BUT, the route / never matched when accessed from localhost/slim_app_dir Because the main url route, from / become /slim_app_dir And I don’t want to create url route named /slim_app_dir , because, i will crazy because i must create url route /slim_app_dir_renamed when i rename the directory.

Please help me Thank you

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 2
  • Comments: 15 (4 by maintainers)

Most upvoted comments

I have a very simple fix for you to get Slim 3 running in a subdirectory:

I will show you how to fix the slim/slim-skeleton app:

  1. Create a new project (or take your existing project) cd c:\xampp\htdocs\ composer create-project slim/slim-skeleton slim3-app

  2. Create a new file: c:\xampp\htdocs\slim3-app\.htaccess

Content of .htaccess

RewriteEngine on
RewriteRule ^$ public/ [L]
RewriteRule (.*) public/$1 [L]
  1. Fixing the script path

Open: c:\xampp\htdocs\slim3-app\src\dependencies.php

Add this lines to fix it:

<?php

// ....

$container['environment'] = function () {
    // Fix the Slim 3 subdirectory issue (#1529)
    // This fix makes it possible to run the app from localhost/slim3-app
    $scriptName = $_SERVER['SCRIPT_NAME'];
    $_SERVER['REAL_SCRIPT_NAME'] = $scriptName;
    $_SERVER['SCRIPT_NAME'] = dirname(dirname($scriptName)) . '/' . basename($scriptName);
    return new Slim\Http\Environment($_SERVER);
};

// ...

Now you can open the app via: http://localhost/slim3-app.

aahhh thank you very much @r3wt and @silentworks , my problem solved! it’s because Garret advises me to not over complicate things… hahahaha thx by the way 😃

Now my ap structure looks like below :

C:\xampp\htdocs
---- slim3-app
-------- libraries
-------- protected
-------- public
------------ css
------------ js
------------ images
-------- vendor
-------- .htaccess
-------- index.php

The source of the problem is putting index.php and .htaccess in slim3-app/public aahh bad…bad… soo… i remove index.php and .htaccess in slim3-app/public and then use only one index.php and .htaccess in slim3-app/

my .htaccess

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

i’m so sorryy… I’ve been prejudiced that this is Slim 3 router bugs.

Thank you very much guys 😃

Why put it in a sub directory at all? just alias it. i have 3 slim apps running in the root directory along with an angularjs front end that just loads from an html index file, all sharing a backend codebase off in another directory. you should be able to do this same thing in apache i’m sure.

example:

location ~ ^/api {
    try_files $request_uri $request_uri/ /api.php?$query_string;
}

location ~ ^/admin {
    try_files $request_uri $request_uri/ /admin.php?$query_string;
}

location ~ ^/debug {
    try_files $request_uri $request_uri/ /debug.php?$query_string;
}

location / {
    try_files $uri /index.html;
}

so in each of api.php,admin.php, and debug.php i have a group wrapping all the routes like so

$app->group('/api',function() use($app){
... routes here
});

Why over complicate things by using an actual directory? i don’t see the advantage of that at all.

@okaprinarjaya, it works for me Thanks!

@okaprinarjaya, Yep, it works for me and I fix it like you said. Thanks!

Make use of Route names and pathFor, otherwise you will have to work out the context of subdirectories by yourself.

$app->get('/', function ($request, $response) {
    if (isset($_SESSION['Auth'])) {
        return $response->withStatus(302)->withHeader('Location', $this->router->pathFor('dashboard'));
    }

    return $this->view->render(
        $response,
        'login/index'
    );
});

$app->get('/dashboard', function ($request, $response) {
    return $response->getBody()->write('I am in the dashboard');
})->setName('dashboard');