When PHP starts up, before it runs a single line of your code, it reads a configuration file. This file tells PHP how to behave — how much memory to allow, how long scripts can run, which extensions to load, how to handle errors. That file is php.ini.
Understanding php.ini is not optional knowledge for a serious PHP developer. Every time a Composer package fails, an extension is missing, or something works on one machine but not another — php.ini is almost always involved.
What Exactly is php.ini
php.ini is a plain text configuration file written in INI format. It is read by PHP once at startup. Every setting inside it controls a specific behavior of the PHP engine.
It is not PHP code. You cannot use variables, functions, or logic inside it. Every line is either a key-value setting, an extension declaration, or a comment.
memory_limit = 256M
max_execution_time = 30
upload_max_filesize = 64M
Three settings. Three behaviors controlled. That's the entire format.
Where is php.ini Located
The location depends on your setup. To find it exactly, run this in your terminal:
php --ini
Output:
Configuration File (php.ini) Path: C:\xampp\php
Loaded Configuration File: C:\xampp\php\php.ini
The second line is what matters — the actual file being loaded right now. This is especially important because multiple PHP installations can exist on one machine, each with their own php.ini, and PHP will only load one of them.
You can also check it from a PHP file:
<?php
echo php_ini_loaded_file();
Or see every loaded configuration file:
<?php
phpinfo();
phpinfo() outputs a full page showing which php.ini was loaded, every setting currently active, and every extension currently available.
The Comment Syntax — Semicolons
INI format uses ; as the comment character. Any line starting with ; is completely ignored by PHP:
; This entire line is a comment
; PHP will never read this
This is where the enable/disable pattern for extensions comes from. When an extension line has a ; in front, PHP skips it entirely:
;extension=gd
Remove the semicolon and PHP loads the extension at startup:
extension=gd
Same line. One character difference. Completely different behavior.
What Are Extensions
PHP's core is intentionally lean. It handles the language itself — variables, loops, functions, classes, file I/O. Everything else — image processing, encryption, database drivers, internationalization — lives in extensions.
Extensions are compiled modules (.dll files on Windows, .so files on Linux/macOS) that add new functions and capabilities to PHP. They ship with PHP but are not all active by default. You enable only what your project needs.
In XAMPP on Windows, all extension files sit here:
C:\xampp\php\ext\
You'll find files like php_gd.dll, php_intl.dll, php_sodium.dll — all available but waiting to be enabled in php.ini.
The Most Important Extensions — What They Do
ext-gd — Image Processing
GD is PHP's built-in image manipulation library.
Enable it:
extension=gd
What it unlocks:
<?php
$image = imagecreatetruecolor(400, 200);
$background = imagecolorallocate($image, 30, 30, 30);
$textColor = imagecolorallocate($image, 255, 255, 255);
imagefill($image, 0, 0, $background);
imagestring($image, 5, 150, 90, "Hello GD!", $textColor);
header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);
Used for generating CAPTCHA images, creating thumbnails, adding watermarks, resizing uploaded photos, drawing charts — anything involving image creation or manipulation.
Laravel's image packages like intervention/image require this extension.
ext-intl — Internationalization
The intl extension provides formatting and language tools that are locale-aware — meaning they respect regional differences in how dates, numbers, and currencies are displayed.
Enable it:
extension=intl
What it unlocks:
<?php
$formatter = new NumberFormatter('en_IN', NumberFormatter::CURRENCY);
echo $formatter->formatCurrency(125000, 'INR');
$dateFormatter = new IntlDateFormatter(
'hi_IN',
IntlDateFormatter::LONG,
IntlDateFormatter::NONE
);
echo $dateFormatter->format(new DateTime());
₹1,25,000.00
18 जून 2026
Used for multi-language applications, e-commerce platforms showing regional pricing, date formatting per locale, and sorting strings correctly across different languages. Symfony's translation component and several Laravel packages depend on this.
ext-sodium — Modern Cryptography
Sodium is a modern, high-level cryptography library. It handles encryption, decryption, digital signatures, and password hashing using algorithms that are considered secure by current standards.
Enable it:
extension=sodium
What it unlocks:
<?php
$key = sodium_crypto_secretbox_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$message = "sensitive user data";
$encrypted = sodium_crypto_secretbox($message, $nonce, $key);
$decrypted = sodium_crypto_secretbox_open($encrypted, $nonce, $key);
echo $decrypted;
sensitive user data
Laravel itself uses Sodium for its encryption layer. JWT libraries, OAuth packages, and any package dealing with tokens or signed payloads typically require this. It became a core PHP extension in PHP 7.2.
ext-zip — ZIP File Handling
Enable it:
extension=zip
Allows PHP to create, read, and extract ZIP archives. Composer itself requires this extension to download and extract packages. If ext-zip is disabled, Composer cannot function.
ext-mbstring — Multibyte String Functions
Enable it:
extension=mbstring
PHP's default string functions like strlen() and strtolower() count bytes, not characters. For ASCII text this works fine. For UTF-8 text — Hindi, Arabic, Chinese, emoji — one character can be 2-4 bytes. mbstring provides multibyte-aware versions:
<?php
$text = "नमस्ते";
echo strlen($text);
echo mb_strlen($text);
18
6
strlen counted bytes — 18. mb_strlen counted actual characters — 6. Almost every Laravel application needs mbstring enabled.
ext-pdo_mysql — MySQL Database Driver
Enable it:
extension=pdo_mysql
PDO (PHP Data Objects) is PHP's database abstraction layer. pdo_mysql is the MySQL-specific driver. Without it, Laravel cannot connect to a MySQL database at all. This is one of the first extensions you enable when setting up a Laravel project with XAMPP.
ext-curl — HTTP Requests
Enable it:
extension=curl
Allows PHP to make HTTP requests to external APIs and services. Laravel's HTTP client (Http::get(), Http::post()) is built on top of Guzzle, which requires cURL. Any package that talks to an external API will need this.
Key php.ini Settings Beyond Extensions
Extensions are not the only thing php.ini controls. These settings directly affect how your Laravel application runs:
Memory Limit
memory_limit = 256M
Maximum RAM a single PHP script can use. Laravel applications with large datasets, complex queries, or image processing can hit the default 128M limit. Increase it for development:
memory_limit = 512M
Max Execution Time
max_execution_time = 30
Seconds before PHP kills a running script. For CLI scripts and long-running jobs, set it to 0 (unlimited):
max_execution_time = 0
File Upload Settings
upload_max_filesize = 64M
post_max_size = 64M
Controls the maximum file size users can upload. Both settings must be updated together — post_max_size must be equal to or larger than upload_max_filesize.
Error Display
display_errors = On
error_reporting = E_ALL
For development, show all errors. For production, always turn this off:
display_errors = Off
log_errors = On
error_log = C:\xampp\php\logs\php_error.log
Multiple php.ini Files — The Common Confusion
This catches many developers off guard. XAMPP runs two different PHP processes:
| Context | PHP Binary | php.ini Used |
|---|---|---|
| Web (Apache) | mod_php inside Apache |
C:\xampp\php\php.ini |
| CLI (Terminal) | php.exe |
C:\xampp\php\php.ini |
Normally they use the same file in XAMPP. But if you have a separate PHP installation on your system — or if your PATH points to a different PHP — CLI and web could be using completely different php.ini files with different extensions enabled.
This is why the classic situation happens — something works in the browser but fails when running php artisan. Always verify which PHP and which php.ini your CLI is using:
php --ini
php -v
Both outputs should match what XAMPP shows in phpMyAdmin's PHP version display.
How Composer Uses This
When you run composer install or composer require, Composer checks which PHP extensions are active in your current php.ini. If a package declares "require": {"ext-gd": "*"} in its composer.json, Composer verifies that ext-gd is enabled before installing.
If it's not enabled, you get:
Your requirements could not be resolved to an installable set of packages.
Problem 1
- intervention/image requires ext-gd * -> it is missing from your system.
The fix is always the same — open php.ini, find the extension line, remove the semicolon, restart Apache from the XAMPP control panel, and run Composer again.
Workflow — Enabling an Extension Step by Step
- Open
php.iniatC:\xampp\php\php.ini - Press
Ctrl + F, search for the extension name — for examplegd - Find the line:
;extension=gd
- Remove the semicolon:
extension=gd
- Save the file
- Restart Apache from XAMPP Control Panel
- Verify it's active:
php -m | findstr gd
If gd appears in the output, the extension is loaded and ready.
The Bottom Line
php.ini is PHP's master configuration file — it decides which features PHP has, how much memory it uses, how errors are reported, and how files are handled. Extensions are modular additions to PHP that stay disabled until you enable them by removing a single semicolon. Every time Composer complains about a missing extension, every time a package fails to install, the solution is almost always in php.ini. Knowing this file deeply means you spend less time debugging environment issues and more time writing actual code.
No comments:
Post a Comment