File types · Explainer

The PHP file (.php)

A PHP file is a plain-text program that a web server runs to build a web page, usually mixing PHP code with HTML. This guide explains what's inside one, why it shows as code or downloads instead of running, the errors worth knowing, and has free sample PHP files to download for testing.

At a glance

Full name
PHP: Hypertext Preprocessor (a recursive acronym; originally Personal Home Page)
Extensions
.php; older sites also use .phtml, .php3 to .php5
MIME type
None registered. Servers send the script's output (usually text/html), never the file; application/x-httpd-php is the name Apache configurations use for the handler
Kind
Plain text: PHP code, often mixed with HTML
Encoding
PHP copies bytes as they are; save as UTF-8 without a BOM
Owner
The PHP Group; development is funded by The PHP Foundation
First released
Created by Rasmus Lerdorf in 1994; source released in June 1995
Supported versions
8.4 and 8.5 (active support), 8.2 and 8.3 (security fixes only), as of October 2026
Runs with
A web server with PHP (PHP-FPM, Apache's mod_php), or the php command
Comments
// line, # line and /* block */
Magic number
None; usually starts with <?php, but may start with HTML

The basics

What is a PHP file?

A .php file holds a program written in PHP, a language made for building web pages on a server. When someone visits a PHP page, the web server runs the file, and the visitor's browser receives whatever it printed: usually HTML, sometimes JSON, an image or a PDF. WordPress, Drupal, Joomla, Laravel and Symfony applications are all made of PHP files.

That makes PHP files different from HTML files. An HTML file is the page; a PHP file is a recipe the server follows to make the page, often a different one for each visitor: their name, their basket, today's prices. The browser can't do this itself, which is why a PHP file needs a server with PHP installed.

The file is plain text, so any text editor can open it and show the code. Opening it in a browser straight from your computer doesn't run it: you see the code, or the browser offers to download it.

Downloaded a file ending in .php?

When a website's download link is a PHP script, such as download.php?id=42, the browser sometimes saves the result under the script's name. The file is whatever the script sent: often a PDF, an image or a ZIP. Open it in a text editor and look at the start: %PDF means a PDF, PK a ZIP, <html a web page. Rename it with the right extension.

Anatomy

What's inside a PHP file

A PHP file is a text file in which <?php … ?> tags mark the code. PHP runs the code and sends everything outside the tags as it is. Here is a small page that lists products from PHP objects, part by part.

products.php
<?php
declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use App\Shop\Product;

$products = [
    new Product('Notebook', 4.50),
    new Product('Pencil', 0.80),
];

function h(string $text): string
{
    return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
}
?>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Shop</title></head>
<body>
  <h1>Products</h1>
  <ul>
  <?php foreach ($products as $product): ?>
    <li><?= h($product->name) ?>: €<?= number_format($product->price, 2) ?></li>
  <?php endforeach; ?>
  </ul>
</body>
</html>
  1. 1<?php

    The opening tag

    Switches from output to code. It must be followed by a space, tab or newline. Anything before it, even one blank line or an invisible byte order mark, is sent to the browser.

  2. 2declare(strict_types=1);

    Strict types

    Must be the first statement in the file. With it, passing a number where a function expects a string is a TypeError instead of a silent conversion.

  3. 3require __DIR__ . '/vendor/autoload.php';

    The Composer autoloader

    Loads the packages installed with Composer and lets PHP find your own classes by name. __DIR__ is this file's folder, so the path works whichever folder the request started from.

  4. 4use App\Shop\Product;

    A namespace import

    Lets the code say Product instead of App\Shop\Product. Under the PSR-4 convention, that class lives in a file called Product.php in a Shop folder.

  5. 5$products = [ … ];

    Variables and arrays

    Variables start with $. Square brackets make an array, PHP's all-purpose list and dictionary.

  6. 6htmlspecialchars($text, ENT_QUOTES, 'UTF-8')

    Escaping output

    Turns <, >, & and quotes into HTML entities, so text from a database or a visitor can't add HTML or scripts to the page (cross-site scripting).

  7. 7?>

    The closing tag

    Switches back to output. Everything until the next <?php goes to the browser unchanged. A file that is all PHP should leave this tag out, as the next section explains.

  8. 8<!DOCTYPE html> …

    Plain HTML

    Sent as it is. The browser only ever receives HTML like this: it never sees the PHP code, only what the code printed.

  9. 9<?php foreach (…): ?> … <?php endforeach; ?>

    A loop around HTML

    The alternative syntax (a colon and endforeach) is made for templates: the HTML between the tags is sent once per product.

  10. 10<?= h($product->name) ?>

    The short echo tag

    <?= is short for <?php echo, and is always available. -> reads a property of an object.

Under the hood

What happens when a server runs a PHP file

  1. 1The browser asks for a page, such as https://example.com/products.php.
  2. 2The web server sees the .php extension and passes the request to PHP instead of sending the file. Usually that's PHP-FPM, a pool of PHP processes behind Nginx, Apache or Caddy; some Apache servers run PHP inside the server with mod_php.
  3. 3PHP compiles the file to opcodes, the instructions its engine runs. OPcache, which comes with PHP, keeps the compiled version in memory, so later requests skip this step until the file changes.
  4. 4PHP runs the code from top to bottom. Text outside the tags and anything printed with echo become the response. header() can set the content type, a redirect or a cookie, but only before any output.
  5. 5The server sends the output to the browser, as text/html unless the script said otherwise.
  6. 6PHP forgets everything. Each request starts from scratch; anything that must last, such as a logged-in user or an order, lives in a session, a database or a file.

On the command line, php script.php runs the same file without a web server, printing the output in the terminal. That's how PHP is used for scripts, scheduled jobs and tools such as Composer.

The big gotcha

Why a PHP file downloads or shows its code instead of running

A PHP file only runs when a server with PHP handles it. Anywhere else it's just text. The usual reasons you see code, or get a download, instead of a page:

Where you opened itWhat you seeWhyFix
Double-clicked on your computerThe code, or a download promptBrowsers can't run PHP, and file:// has no serverRun php -S localhost:8000 in the folder and open the page through it
A static host (GitHub Pages, object storage, 99helpers)The code as plain textStatic hosts send files as they are and never run server codeUse a host with PHP, or export the pages as HTML
Your PHP hosting, after a changeA download of the .php fileNo PHP handler for that file, often an .htaccess line naming a PHP version the host removedRemove or update the handler line, or pick the PHP version again in the hosting panel
Your PHP hostingCode from <? onwards in the page sourceShort open tags (<? without php) are switched off on that serverUse <?php (and <?= for echo) everywhere

A server that shows PHP source is showing whatever is in it, including database passwords in configuration files. If your live site ever does this, take it offline until PHP is running again, then change those passwords.

How to

How to run, edit and check a PHP file

WindowsmacOSLinux
Get PHPThe Windows builds from php.net, a package such as XAMPP, or PHP inside WSLHomebrew (brew install php); recent macOS versions don't include PHPThe distribution's php-cli package
Run a scriptphp script.phpphp script.phpphp script.php
Serve pagesphp -S localhost:8000php -S localhost:8000php -S localhost:8000
terminal
# In the folder that holds your PHP files:
php -S localhost:8000

# then open http://localhost:8000/sample-page.php in a browser.
# Serve a subfolder as the document root instead:
php -S localhost:8000 -t public/

The built-in server (in PHP since 5.4) serves the current folder and returns index.php or index.html for a folder address. The PHP manual is clear that it's for development and testing only: by default it's a single process that stalls while one request is busy, and it shouldn't be used on a public network. php -v shows your version and php -m the installed extensions.

  • Read or edit it: any plain-text editor works. VS Code with a PHP extension such as Intelephense, or PhpStorm, add autocompletion and error checking.
  • Check the syntax without running it: php -l file.php prints No syntax errors detected or the parse error, and exits with status 255 on failure.
  • Find bugs before they run: static analysers such as PHPStan and Psalm catch type errors and calls to methods that don't exist.
  • Format: PHP-CS-Fixer or PHP_CodeSniffer apply the PSR-12 or PER coding style.
  • Turn a PHP page into static HTML: run it and save the output, php page.php > page.html, or save the page from your browser while a server runs it. Pages that depend on a database or form input only keep the content of that moment.

The rules

Tags, encodings, file names and project layout

  • Leave out the closing tag in pure PHP files. The PHP manual recommends it: a newline or space after a final ?> is sent as output, which can break headers, sessions, downloads and JSON. Files that end in HTML, like templates, keep their tags.
  • Use <?php and <?= only. The short <? tag can be switched off with the short_open_tag setting, and the PSR-1 coding standard allows only the two long forms.
  • UTF-8 without a BOM. PHP doesn't decode the file; it outputs strings byte for byte. A byte order mark before <?php is output too, before your code runs, which causes "headers already sent" warnings and makes declare(strict_types=1) or a namespace line a fatal error. PSR-1 requires UTF-8 without a BOM.
  • A shebang is allowed for command-line scripts: PHP skips a first line starting with #!, so #!/usr/bin/env php above <?php works.
  • One class per file, named after the class. The PSR-4 autoloading standard maps App\Shop\Product to src/Shop/Product.php, matching upper and lower case, which matters on Linux servers. PSR-1 adds that a file should either declare things or do things (print, change settings), not both.
  • Keep only the entry point in the web root. Modern apps put index.php in a public/ folder that the server serves, and everything else, including configuration with passwords, outside it.
project layout
my-site/
  composer.json         dependencies and autoload rules
  composer.lock         exact versions Composer installed: commit it
  vendor/               installed packages; vendor/autoload.php loads them
  public/               the web server's document root, the only folder online
    index.php           the entry point: every request starts here
    style.css
  src/
    Shop/
      Product.php       class App\Shop\Product (PSR-4: one class per file)
  config/
    database.php        settings and passwords, outside public/

Versions

PHP versions and which ones are still supported

Each PHP version gets two years of active support (bug and security fixes), then two years of security fixes only. A PHP file doesn't declare its version; projects state it in composer.json, for example "php": ">=8.2". As of October 2026:

Supported PHP versions, from php.net
VersionReleasedActive support untilSecurity fixes until
8.520 November 202531 December 202731 December 2029
8.421 November 202431 December 202631 December 2028
8.323 November 202331 December 202531 December 2027
8.28 December 202231 December 202431 December 2026

Anything older, including the 7.x versions many hosts still offer, gets no fixes from the PHP project. The big steps for code were PHP 5 (2004, a new object model), PHP 7 (2015, a much faster engine and scalar type declarations) and PHP 8 (2020, named arguments, match and a JIT compiler). Code written for PHP 7 often needs small changes for PHP 8, which turned many old warnings into errors.

Troubleshooting

PHP errors you'll meet on a server, and what they mean

Error messageUsual causeFix
A blank white page, or HTTP 500A fatal error, with error display switched off (as it should be on a live site)Read the server's PHP error log, or switch on display_errors on a development copy
Parse error: syntax error, unexpected …A missing semicolon, bracket or quote, often on the line before the one reportedRun php -l file.php
Cannot modify header information - headers already sent by (output started at …)Output before header(), setcookie() or session_start(): a BOM, whitespace before <?php or after ?>, or an echoGo to the file and line named in the message; remove the BOM or the closing tag
strict_types declaration must be the very first statementA BOM or text before <?phpSave as UTF-8 without a BOM
Call to undefined function mb_strlen()The extension (here mbstring) isn't installed or enabledInstall or enable it; php -m lists what's loaded
Failed opening required 'vendor/autoload.php'Composer's packages were never installed on this machineRun composer install
Allowed memory size of … bytes exhaustedThe script needed more than memory_limit (128 MB by default)Process data in smaller pieces, or raise the limit
Maximum execution time of 30 seconds exceededA web request ran past max_execution_time (no limit on the command line)Move long jobs to a command-line script or a queue

Security

Is it safe to open a PHP file, and what goes wrong on servers

Opening a .php file on your own computer is safe: browsers and text editors only show the code. The risks are on servers, where PHP files run with the web server's permissions:

  • Uploaded PHP files. If an upload form lets someone put a .php file (or photo.php.jpg on a badly configured server) into a folder the server runs PHP in, they can run any code on your server. This "web shell" is one of the most common ways PHP sites are taken over. Store uploads outside the web root, check file types by content, and switch off PHP in upload folders.
  • SQL injection. Building database queries by pasting in form values lets attackers rewrite the query. Use prepared statements with PDO or mysqli.
  • Cross-site scripting. Escape everything you print with htmlspecialchars(), as the sample does.
  • Including files by user input. include $_GET['page'] lets visitors choose which file runs. Map allowed values to files instead.
  • Secrets in PHP files. Keep database passwords and API keys in a configuration file or environment variables outside the web root, so a server misconfiguration can't publish them.
  • Old PHP versions get no security fixes. Check the version your host runs against the table above.

Free downloads

Sample PHP files to download

Free sample PHP files for testing servers, editors, syntax highlighters, linters and upload filters. All pass php -l and run with PHP 8.2 or later, except sample-syntax-error.php, which fails on purpose.

sample-page.php · 3.4 KBDownloadOpen
Loading…

What's inside sample-page.php

The preview shows the file as source, the way a static host serves it. Open it in a text editor to follow the numbered comments, or run php -S localhost:8000 in its folder and open /sample-page.php to see the page PHP builds from it.

  1. Comments 1 and 2: the opening tag and strict types

    <?php on the first line, a comment explaining how to run the file, then declare(strict_types=1) as the first statement.

  2. Comment 3: data

    An array with string keys holding a week of opening hours, with null for a closed day.

  3. Comment 4: an escaping function

    h() wraps htmlspecialchars() so every value printed into the page is safe against cross-site scripting.

  4. Comments 5 and 6: input and dates

    $_GET['name'] ?? '' reads an optional ?name= from the address, and a DateTimeImmutable with a named time zone works out today's day.

  5. Comment 7: the closing tag

    PHP stops and the HTML that follows is sent as it is, up to each <?= or <?php tag inside it.

  6. Comments 8 and 9: templates

    Short echo tags print values, and a foreach … endforeach loop writes one table row per day, marking today's row with a class.

  7. Comments 10 and 11: a form and constants

    A GET form that sends a name back to the same file, and PHP_VERSION in the footer, so you can see which PHP built the page.

All sample PHP files

  • Commented PHP page

    sample-page.php · 3.4 KB (3,473 bytes)

    A web page mixing PHP and HTML: opening hours with today highlighted, a greeting form and escaped output, with numbered comments explaining each part.

    • Checking whether a server runs PHP or serves it as text
    • Teaching how PHP and HTML mix
  • Command-line script

    sample-cli.php · 2.1 KB (2,169 bytes)

    A pure-PHP length converter with a #!/usr/bin/env php shebang and no closing tag. Uses an enum, match, $argv, STDERR and exit codes: php sample-cli.php 5 km mi.

    • Testing PHP on the command line and in CI
    • An example of a file with the closing tag left out
  • UTF-8 encoding test

    sample-utf8.php · 1.9 KB (1,946 bytes)

    Greetings in 12 languages plus symbols and emoji, comparing strlen() with mb_strlen(), strtoupper() with mb_strtoupper(), and JSON with and without escaped Unicode.

    • Spotting encoding bugs in editors and pipelines
    • Checking that the mbstring and intl extensions are installed
  • UTF-8 with a byte order mark

    sample-bom.php · 1.0 KB (1,034 bytes)

    Starts with the bytes EF BB BF before <?php. When run, it reports that output had already started at line 1, which is what breaks header() and sessions.

    • Reproducing "headers already sent" problems
    • Checking whether an editor or pipeline adds or strips a BOM
  • Missing semicolon (deliberate syntax error)

    sample-syntax-error.php · 541 bytes

    An echo without a semicolon. Clearly labelled; php -l reports unexpected token "echo" on line 16 and exits with status 255.

    • Testing how editors, linters and CI report parse errors
    • Showing that PHP reports the line after the mistake
  • 100 KB PHP file

    sample-100kb.php · 100 KB (102,400 bytes)

    A constant array of Roman numerals from 1 to 3,999 and a function that checks every one, padded with a comment to exactly 102,400 bytes.

    • Upload and size-limit tests
    • Parser, highlighter and OPcache tests

Ways to test with them

  • Does the server run PHP? Upload sample-page.php and open it. A page with an opening-hours table means PHP ran; the source code means it didn't.
  • Lint in CI: php -l should pass for every sample except sample-syntax-error.php, which must fail with exit status 255.
  • BOM handling: run sample-bom.php; if it no longer reports output at line 1, something on the way removed the BOM.
  • Upload filters: many upload forms rightly refuse .php files. Use the samples to confirm yours does, including the exactly 102,400-byte sample-100kb.php for size limits.

Free to use for testing, teaching and demos, commercially or not, with no attribution needed. A link back to this page is always appreciated.

Put it online

Have a PHP file? Share its code with a link.

Drop a .php file on 99helpers and it gets its own address in seconds. The link shows the source as plain text: the code is never run on our servers, so it's a way to share PHP for review or download, not to host a PHP site.

Questions

PHP files, frequently asked

What is a .php file?

A PHP source file: a program, often mixed with HTML, that a web server runs to build a web page. The browser receives only the output, never the PHP code.

How do I open a PHP file?

To see or edit the code, open it in a text editor such as VS Code or Notepad. To see the page it makes, it has to run on a server with PHP, such as the built-in one: php -S localhost:8000.

Why does my browser download the PHP file instead of showing the page?

The server isn't running it through PHP: PHP isn't installed, isn't set up for that extension, or a handler line in .htaccess points to a PHP version that's gone. Opened from your own disk, a PHP file never runs.

I downloaded a file ending in .php. What is it?

Usually the file you wanted, saved under the name of the script that sent it. Open it in a text editor: %PDF at the start means a PDF, PK a ZIP. Rename it with the right extension.

Should I end a PHP file with ?>?

Not if the file contains only PHP. The PHP manual recommends leaving it out, because whitespace after it is sent as output and can cause "headers already sent" errors.

Which PHP version should I use?

A supported one: as of October 2026 that's 8.4 or 8.5 for new projects, with 8.2 and 8.3 still getting security fixes. PHP 8.2's security support ends on 31 December 2026.

Can I convert a PHP file to HTML?

You can save its output: run php page.php > page.html, or save the page from a browser while a server runs it. You get the page as it was at that moment, without the dynamic parts.

Is it safe to open a .php file?

Yes, on your own computer: a browser or text editor only shows the code. PHP files are dangerous on servers that let visitors upload them, because the server would run them.

Related formats

Other file types explained

Keep going

Related

Sources

Last reviewed 27 October 2026.