Après une migration de serveur, la page d'accueil n'affiche plus qu'une ligne : "No input file specified.". Ce message ne vient pas d'Apache ni de Nginx, mais de PHP : il le renvoie quand le chemin du script qu'il reçoit du serveur web ne désigne aucun fichier qu'il peut ouvrir. La correction porte donc sur ce chemin (racine du site, paramètre SCRIPT_FILENAME), sur les droits des dossiers ou sur deux réglages de PHP. Nous avons reproduit chaque cause avec Nginx devant PHP-FPM et devant php-cgi.
Qui affiche "No input file specified", et quand ?
Le serveur web passe la requête à PHP en FastCGI, avec le chemin complet du script dans le paramètre SCRIPT_FILENAME (la documentation de Nginx : "The SCRIPT_FILENAME parameter is used in PHP for determining the script name"). Si PHP ne peut pas ouvrir ce fichier, il répond lui-même, et le texte dépend de la façon dont PHP tourne :
| Cause reproduite | PHP-FPM | php-cgi |
|---|---|---|
Aucun fichier à ce chemin (URL inexistante, mauvaise racine, SCRIPT_FILENAME absent ou ancien) |
404 File not found. |
404 No input file specified. |
| Dossier parent sans droit de traversée (700 ou 644, propriétaire root) | 404 File not found. |
404 No input file specified. |
| Fichier illisible (600, propriétaire root) | 403 Access denied. |
403 Access denied. |
Script en dehors d'open_basedir |
404 No input file specified. |
404 No input file specified. |
php-cgi est le mode FastCGI historique de PHP : c'est par exemple lui que Laragon lance sous Windows derrière Nginx (processus php-cgi.exe). Avec PHP-FPM, le même problème s'affiche le plus souvent en "File not found.".
Le chemin envoyé à PHP est-il le bon ?
C'est la première chose à vérifier. Voici le bloc minimal qui fonctionne :
# /etc/nginx/conf.d/site.conf
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000; # adresse de PHP-FPM ou de php-cgi
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
Trois variantes ont produit l'erreur dans nos tests :
SCRIPT_FILENAMEabsent. Le fichierfastcgi_paramslivré avec Nginx ne le définit pas (seulfastcgi.confle contient) : uninclude fastcgi_params;seul ne suffit pas.- Un ancien chemin écrit en dur, du type
/home/ancien/public$fastcgi_script_name, recopié depuis l'ancien serveur. - Une mauvaise racine (
root), qui pointe un niveau trop haut ou trop bas.
Pourquoi une application Laravel doit pointer sur public/ ?
La documentation de Laravel demande que toutes les requêtes arrivent sur public/index.php et donne une configuration Nginx de départ, dont voici les lignes utiles :
# /etc/nginx/sites-available/example.com
root /srv/example.com/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
Avec root sur la racine du projet au lieu de public, l'adresse /clients/42 renvoie "No input file specified." (php-cgi) ou "File not found." (PHP-FPM), puisqu'il n'y a pas d'index.php à cet endroit. Plus grave : dans le même test, /composer.json et /storage/logs/laravel.log étaient servis tels quels. La règle sur les fichiers cachés protège .env, pas le reste du projet. Remettre root sur public corrige les deux problèmes.
Les droits des fichiers et des dossiers sont-ils corrects ?
PHP tourne sous un utilisateur limité (www-data dans nos conteneurs) : il doit pouvoir lire le fichier et traverser chaque dossier du chemin (droit x). Un dossier en 644 suffit à provoquer l'erreur, même si le fichier lui-même est lisible ; en 711, tout fonctionne.
Inutile d'écrire un script PHP récursif pour remettre des droits standards, find le fait :
find /var/www/app -type d -exec chmod 755 {} + find /var/www/app -type f -exec chmod 644 {} +
Dans notre test, un fichier en 600 et un dossier en 777 sont bien revenus à 644 et 755. Attention : les fichiers en 644 perdent leur droit d'exécution, à remettre sur vos éventuels scripts shell.
Laravel doit en plus écrire dans storage et bootstrap/cache : la documentation demande que l'utilisateur du serveur web en ait le droit. Avec ces dossiers à root, l'écriture d'un fichier de log a échoué ; après ce changement de propriétaire, elle a réussi :
cd /var/www/app chown -R www-data:www-data storage bootstrap/cache
Pas besoin de 777 : donner ces deux dossiers au bon utilisateur suffit.
open_basedir ou cgi.fix_pathinfo peuvent-ils être en cause ?
Oui, ce sont les deux réglages PHP à regarder ensuite.
open_basedirlimite les fichiers que PHP peut ouvrir. La documentation précise : "When the file is outside the specified directory-tree, PHP will refuse to access it." Avecopen_basedir=/var/www/autreet un site dans/var/www/app, PHP-FPM comme php-cgi ont répondu "No input file specified.". Vérifiez la valeur dans lephp.ini, le pool PHP-FPM ou le panneau de l'hébergeur après une migration.cgi.fix_pathinfo(1 par défaut) permet à PHP de retrouverindex.phpdans une adresse comme/index.php/clients/42. Avec la configuration Laravel ci-dessus etcgi.fix_pathinfo=0, cette adresse a renvoyé "No input file specified." (php-cgi) ou "Access denied." (PHP-FPM, qui n'exécute que les fichiers en.phpselonsecurity.limit_extensions). Les adresses habituelles, comme/clients/42, continuaient de fonctionner.
Rechargez Nginx après chaque changement (nginx -s reload) et redémarrez PHP-FPM après une modification du php.ini ou du pool. Un réglage passé par fastcgi_param PHP_ADMIN_VALUE est resté actif dans un des processus PHP-FPM après son retrait de la configuration, jusqu'au redémarrage.
Ce type de panne arrive surtout lors d'un changement de serveur : c'est une des vérifications que nous faisons quand nous hébergeons et maintenons une application. Pour savoir ce qui a changé sur le serveur avant la panne, voir aussi trouver les derniers fichiers modifiés.
- Le message vient de PHP (php-cgi surtout), pas d'Apache : le chemin reçu ne désigne aucun fichier lisible.
- Vérifier d'abord
rootetSCRIPT_FILENAME; pour Laravel,rootpointe surpublic. - Dossiers traversables (755), fichiers lisibles (644),
storageetbootstrap/cacheà l'utilisateur du serveur web. - Ensuite seulement :
open_basediretcgi.fix_pathinfo.
Testé avec Nginx 1.31.6, PHP-FPM 8.3.35 et php-cgi 8.3.35 (Docker).
Questions fréquentes
Pourquoi PHP-FPM affiche "File not found." et pas "No input file specified." ?
Les deux modes de PHP ne répondent pas avec le même texte. Dans nos tests, pour un script introuvable, PHP-FPM a répondu "File not found." et php-cgi "No input file specified." ; pour un script hors open_basedir, les deux ont répondu "No input file specified.".
Faut-il mettre les dossiers en 777 pour corriger les droits ?
Non. Des dossiers en 755 et des fichiers en 644 suffisent pour que PHP lise le site. Seuls storage et bootstrap/cache doivent être modifiables, en les donnant à l'utilisateur du serveur web (www-data par exemple).
Où voir la requête en erreur côté serveur ?
Dans le journal d'accès de PHP-FPM s'il est activé (réglage access.log du pool, non défini par défaut) : la requête y apparaît avec le code 404. Le journal d'accès de Nginx montre aussi le code renvoyé.