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 outsidepublic 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 publicWhen 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.