Adding PHP
Chapter 4 — PHP
PHP is the glue between your web server and your database. This chapter covers two installation paths — the version that ships with Debian 12 Bookworm's main repository (PHP 8.2) and the newer PHP 8.3 available via the Sury third-party repository — along with the extensions you'll need for a real-world site, the key configuration settings to change from their defaults, and how to verify everything is working for both Apache and Nginx.
Option A — PHP 8.2 (Debian Main Repository)
Installation
PHP 8.2 is available directly from Debian's main repository — no GPG keys or third-party sources to configure. The package you need depends on your web server.
Option B — PHP 8.3 (Sury Repository)
The deb.sury.org repository is maintained by Ondřej Surý, a Debian Developer who maintains the official PHP packages. It is widely used in production and is the standard way to get PHP versions newer than what Debian ships.
update-alternatives --set php /usr/bin/php8.3 sets which binary
php calls on the command line. The web server module (mod_php or
FPM) is controlled separately — make sure Apache/Nginx points at the FPM
socket for your chosen version.
Essential Extensions
A bare PHP install will process scripts, but you'll need extensions for database access, image handling, and character encoding. Below are the extensions used by Philip's Learning Blog and other common PHP sites.
php -m to list all
loaded modules, or php -m | grep -i mysql to confirm a specific one.
The output from phpinfo() in a browser shows the full picture including
configuration values.
Configuration — php.ini
PHP uses separate php.ini files for CLI and for each SAPI (Apache mod_php
and PHP-FPM have their own). The paths depend on the PHP version.
| Context | php.ini path (PHP 8.2) | php.ini path (PHP 8.3) |
|---|---|---|
| Apache (mod_php) | /etc/php/8.2/apache2/php.ini | /etc/php/8.3/apache2/php.ini |
| PHP-FPM (Nginx) | /etc/php/8.2/fpm/php.ini | /etc/php/8.3/fpm/php.ini |
| CLI (command line) | /etc/php/8.2/cli/php.ini | /etc/php/8.3/cli/php.ini |
Recommended Changes
Open the appropriate php.ini for your web server SAPI and adjust
these values. The defaults are conservative — fine for shared hosting, too
restrictive for a real development machine.
| Setting | Default | Recommended | Why |
|---|---|---|---|
| memory_limit | 128M | 256M | Enough headroom for image processing and Composer installs. |
| upload_max_filesize | 2M | 20M | Allows uploading images and documents without hitting the limit. |
| post_max_size | 8M | 25M | Must be larger than upload_max_filesize — controls total POST body. |
| max_execution_time | 30 | 60 | Prevents slow scripts from hanging the server indefinitely. |
| display_errors | Off | On (dev only) | Show errors in the browser during development. Set to Off on production. |
| error_reporting | E_ALL & ~E_DEPRECATED | E_ALL | Catch everything including deprecation notices during development. |
| date.timezone | (empty) | Europe/London | Avoids "It is not safe to rely on the system's timezone" warnings. |
display_errors = On leaks internal
paths and logic to the browser. Always set it to Off on a publicly
accessible server, and log errors to a file instead using
log_errors = On and error_log = /var/log/php_errors.log.
Connecting PHP to Apache
When you install php (or libapache2-mod-php8.2), the
module is enabled automatically. You can verify this and ensure the right module
is active:
No virtual host changes are needed — Apache handles .php files
automatically via mod_php as long as the module is loaded.
Connecting PHP to Nginx (PHP-FPM)
Nginx does not embed a PHP interpreter. Instead it passes .php
requests to a separate PHP-FPM (FastCGI Process Manager) process via
a Unix socket. Your Nginx server block needs a location ~ \.php$ block
pointing at that socket.
Verify the FPM socket path
Update the Nginx server block
Add or confirm the PHP location block inside your server {} block.
This is the block introduced in Chapter 2 for the Nginx virtual host.
Testing the PHP Installation
Step 1 — phpinfo() test page
Create a temporary test file in your web root to confirm PHP is executing:
Visit http://<your-server-ip>/info.php in a browser. You should
see the purple PHP information page listing your version, loaded extensions, and
all configuration values.
phpinfo()
page exposes your server configuration to anyone who can reach it.
sudo rm /var/www/osztromok.com/public_html/info.php
Step 2 — Command-line version check
Step 3 — PHP-to-database connection test
This quick script confirms PHP can actually open a PDO connection to your MariaDB / MySQL database. Run it from the CLI — no browser needed.
Installing Composer
Composer is PHP's dependency manager — the equivalent of npm for Node.
It's not strictly required to run Philip's existing site, but it's needed for
any modern PHP framework (Laravel, Symfony, FastAPI-style microframeworks like Slim)
or if you install libraries via require statements.
PHP Management Commands
| Task | Apache (mod_php) | Nginx (PHP-FPM) |
|---|---|---|
| Restart PHP after config change | sudo systemctl restart apache2 | sudo systemctl restart php8.2-fpm |
| Check PHP-FPM status | apache2ctl -M | grep php | sudo systemctl status php8.2-fpm |
| View FPM error log | — | sudo tail -f /var/log/php8.2-fpm.log |
| List installed extensions | php -m | php -m |
| Install a new extension | sudo apt install php-<name> | sudo apt install php8.2-<name> |
| Confirm active php.ini | php --ini | php --ini |
| OPcache status | php -r "echo opcache_get_status()['opcache_enabled'] ? 'enabled' : 'disabled';" | |
Quick-Verification Checklist
- PHP version matches expectation —
php --versionshows 8.2.x or 8.3.x. - Browser test page works —
info.phpreturns the PHP purple page, then removed. - All required extensions loaded —
php -mshows mysql, mbstring, curl, gd, xml, zip. - Database connection succeeds —
db_test.phpprints "Connected OK", then removed. - OPcache enabled — improves every page load with zero code changes.
- php.ini tuned for environment — memory, upload limits, timezone set, display_errors correct for dev/prod.
- FPM socket active (Nginx only) —
/run/php/php8.2-fpm.sockexists, Nginx reload clean.