Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

The public folder and the web server

A Slim application has no separate file for each page. Every request — /, /about, /posts/5 — is received by one file, public/index.php, which then decides what code to run. Such a file is called a front controller.

Why a public folder

The site root is not the project folder but only public. The browser can reach only what lies inside it:

blog/
├── public/          ← site root
│   └── index.php
├── vendor/          ← not reachable from outside
└── composer.json    ← not reachable from outside

public holds index.php and, later, styles, scripts and images. Code, settings and passwords stay one level up and cannot be opened through the site address.

The built-in server

The command from the previous lesson already does everything needed:

php -S localhost:8080 -t public

When no file in public matches the address, the built-in server passes the request to index.php by itself. Real web servers must be told this rule explicitly.

Apache

Create the file public/.htaccess by hand:

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

The rule reads: if the request is not for an existing file or folder, run index.php. The server returns public/css/style.css itself, while /posts/5 goes to Slim. The site's DocumentRoot must point to blog/public, and the mod_rewrite module must be enabled.

Nginx

In Nginx the same rule goes into the site configuration:

server {
    server_name blog.example.com;
    root /var/www/blog/public;
    index index.php;
 
    location / {
        try_files $uri /index.php$is_args$args;
    }
 
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.4-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    }
}

The try_files line looks for a file first and, if there is none, passes the request to index.php.

A site in a subfolder

If the site opens not at the domain root but at an address like example.com/blog/, tell Slim the base path:

// public/index.php
$app = AppFactory::create();
$app->setBasePath('/blog');

After that the /about route answers at /blog/about.

Common mistake

If the site root points to the project folder instead of public, any visitor can open internal files at /composer.json or /vendor/.... And if on Apache the home page works but every other address returns the server's own 404 error, the .htaccess rule did not fire: check that the file is inside public and that mod_rewrite is enabled.

Thanks for reading!

Donate to the site — we work hard for you.