# PHP Logs: error_log, display_errors, and Fatal Errors

> PHP logs in practice: where to find error_log, how display_errors differs from log_errors, and how to read a fatal error log line.

## Where to Find PHP Logs: error\_log and the File Path

PHP writes error messages to whatever the error\_log directive points to in php.ini or in the PHP-FPM pool config. You can find the exact path without editing any files — the php -i command shows the actual value the interpreter uses right now.

```
php -i | grep error_log
```

For sites running Nginx and PHP-FPM, a typical path is /var/log/php8.3-fpm.log for errors from the pool itself, plus a separate error\_log inside the pool block for errors from one specific site. If error\_log is not set explicitly, PHP-FPM writes to the shared system log, and finding one site's error among hundreds of unrelated lines there is hard.

## display\_errors vs log\_errors: Different Jobs

display\_errors prints the error text straight into the HTML page, log\_errors writes it to a file. In production, these directives should run in opposite modes.

```
display_errors = Off
log_errors = On
error_log = /var/log/php/app-error.log
```

Showing errors in the browser leaks information about file paths, library versions, and database structure, which ties directly into the article [on PHP security through php.ini settings](https://www.zevshost.net/en/kb/php-security-hardening-ini/). Logging to a file, on the other hand, should always be enabled, even in production.

## Reading a Typical Fatal: Allowed Memory Size Exhausted

A log line looks like this: PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) in /var/www/app/import.php on line 84. The number 134217728 bytes is 128 megabytes, the [memory\_limit](https://www.zevshost.net/en/kb/php-ini-memory-upload-limits/) value. The line means the script ran out of memory at the exact moment it tried to allocate 20 more kilobytes, not overall.

The first step is not to raise memory\_limit blindly but to open the file at that exact line and see what happens there: most often it is loading an entire query result into an array or processing a whole file instead of reading it in chunks. If the script runs from cron, the difference in limits between CLI and FPM is covered in the article [on PHP in cron and how CLI differs from FPM](https://www.zevshost.net/en/kb/php-cli-vs-fpm-cron/).

## error\_reporting Levels: What the Constants Mean

| Constant | What It Catches | Worth Enabling in Production |
| --- | --- | --- |
| E\_ERROR | Fatal errors, the script stops | yes |
| E\_WARNING | Non-critical runtime errors | yes, to the log |
| E\_DEPRECATED | Outdated language constructs | yes, to the log |
| E\_NOTICE | Access to an uninitialized variable | optional |
| E\_STRICT | Code style recommendations | no, too noisy |

A typical production value is error\_reporting(E\_ALL & ~E\_DEPRECATED & ~E\_STRICT), and everything in that set always goes to error\_log, never to the screen.

## Common Log Entries and What They Mean

- PHP Parse error: syntax error, unexpected token — an error in the code itself, the script never even started, the deploy is broken.
- PHP Fatal error: Uncaught Error: Call to a member function on null — calling a method on an object that was never created, usually after a failed database query.
- PHP Warning: file\_put\_contents failed to open stream — missing write permission on the directory, or the directory does not exist.
- PHP Deprecated: Implicit conversion from float to int loses precision — the code is aging and needs a fix before the next PHP upgrade.
- PHP Fatal error: Maximum execution time exceeded — the script hit max\_execution\_time, not memory\_limit, and needs a different fix.

## Summary: Checklist for Configuring PHP Logging

- display\_errors = Off and log\_errors = On are set separately for the web mode and for CLI.
- error\_log points to a specific site file, not the shared system log.
- Log rotation is configured through logrotate so the disk does not fill up within a month.
- error\_reporting includes E\_ALL without E\_DEPRECATED and E\_STRICT in production.
- Every fatal from the log is tied to a file and a line, not just to the error text.

---

Source: https://www.zevshost.net/en/kb/php-logi-oshibok-razbor/
