---
title: "__FILE__: The Magic Constant With Specific Usage"
url: https://www.exakat.io/__file__-the-magic-constant-with-specific-usage/
date: 2026-07-24
modified: 2026-07-24
author: "dams"
description: " __FILE__: The Magic Constant With Specific Usage Every older PHP developer has meet __FILE__ early, usually while copy-pasting a WordPress plugin header from a tutorial written in 2009. There are..."
categories:
  - "Code auditing"
tags:
  - "__FILE__"
  - "tutorial"
image: https://www.exakat.io/wp-content/uploads/2026/07/study.320.jpg
word_count: 895
---

# __FILE__: The Magic Constant With Specific Usage

#  __FILE__: The Magic Constant With Specific Usage

Every older PHP developer has meet `__FILE__` early, usually while copy-pasting a WordPress plugin header from a tutorial written in 2009. There are lots of blogs posts documenting it: it is also quite famous outside the PHP universe. Nowadays, however useful is this magic constant, it seems it has run its course, and has found a niche usage.

So let's check how `__FILE__` is actualy used for, aka the audit nobody asked for.

## What it actually does

`__FILE__` gives the full, absolute, symlink-resolved path to the file it's written in. Not the file that included it, not the file that's executing right now, not the file you wish was returned when you're three `require`s deep in a legacy framework: the file where the literal string `__FILE__` sits in the source code, in the underlying operating system. It's about as reliable as a magic constant gets, which in PHP is a genuinely rare compliment.

## Case 1: Who actually wants the file name?

There's a small, honest family of use cases where the filename itself is the payload:

- Logging and debugging: `__FILE__ . ':' . __LINE__`, the stack trace's poor cousin, still useful when you don't have the budget for a real one.
- WordPress plugin identity: `register_activation_hook(__FILE__, 'activate')`. WordPress uses your plugin's own file path as its primary key. This has worked since 2004 and will presumably outlive us all.
- CLI entry-point detection: comparing `__FILE__` to `realpath($argv[0])` to figure out if you're the main CLI script being called or just an inclusion somewhere else.
- Cache keys: `md5(__FILE__)` is convenient, until you deploy with timestamped release directories and every deploy invalidates your entire cache because the path changed by sixteen characters. Ask me how I know.

## Case 2: You actually wanted __DIR__ all along

This is the overwhelming majority of `__FILE__` sightings in the wild, and it's a bit of a museum piece. Before PHP 5.3, when the application actually wanted `the current directory`, it used:

Then PHP 5.3 shipped, `__DIR__` arrived, and this became:

Same result, minus a function call PHP doesn't need to make. `__FILE__` is a compile-time constant; so is `__DIR__`. `dirname(__FILE__)` is not: it's a compile-time constant fed into a runtime function call, purely so it can hand back something the compiler could have given for free. It's the software equivalent of taking the stairs down one floor to use the elevator on the ground floor.

And yet. Fifteen years later, `dirname(__FILE__)` is still out there, patiently including config files in codebases that also use match expressions and readonly properties. PHP's greatest talent is backward compatibility; its second greatest talent is convincing developers they don't need to use it.

## The gotchas nobody puts in the tutorial

A few things the copy-paste snippets never mention:

- Inside `eval()`, `__FILE__` stops being a clean path and starts looking like `/app/Template.php(42) : eval()'d code`. Great for debugging, terrible for anything expecting a real filesystem path. Another good reason to avoid using `eval()`.
- Inside a trait, `__FILE__` and `__LINE__` resolve to the trait's own file, not the class using it. That tends to yield a view surprises. `__CLASS__` gives the using class; `__FILE__` doesn't play along. PHP's magic constants are not a family that agrees on anything.
- Inside a Phar, `__FILE__` returns a `phar://` stream path. If the code assumes it can hand that straight to a raw filesystem call, it's going to have a bad day the moment someone packages your library.
- On case-insensitive filesystems, the classic "prevent direct access" trick, with `basename(__FILE__) == basename($_SERVER['SCRIPT_NAME'])`, can quietly not mistake uppercase with lowercase. Which brings us to the trick itself.

## The direct-access check deserves a proper eulogy

You've seen this one:

This pattern has been copy-pasted into more `config.php` files than any human will ever audit. It compares two basenames and calls it security. It doesn't stop the file from being included by something malicious, it can be fooled by rewrite rules, and on top of all that it's solving a problem that architecture already solved decades ago: don't put files you don't want requested directly inside the web root. A `src/` directory next to, not inside, `public/` achieves the same goal with zero runtime checks and zero string comparisons. But that requires deciding on a folder structure before writing the `exit()`, which is apparently the harder problem.

## Where things stand today

Grep a modern Composer-based codebase and `__FILE__` has mostly retreated to the places it's actually earned: front controllers, bootstrap scripts, test fixtures, and, thanks for it, WordPress, where it remains as load-bearing as ever. Everywhere else, Composer's autoloader quietly did to manual path resolution what `__DIR__` did to `dirname(__FILE__)`: made it mostly unnecessary, while leaving it perfectly capable of still working, forever, out of sheer PHP stubbornness.

In the end, this audit made me wonder: is this a necessary PHP feature, but just not for everyone? May be it is supposed to be used by the underlying framework, hence it is needed, but then, never actually accessed by any other code ABOVE the framework. Deprecate it? Nah, too extreme. Spot it in the code with static analysis, and label it as 'not unless you're writing a framework/cms' kind of retractation.