php.ini Ayarları: Bellek Sınırı ve Upload Boyutu Nasıl Yapılandırılır

Bir WordPress sitesi yavaşlıyor, kullanıcılar büyük dosya yükleyemiyor ya da PHP uygulaması hafıza yetersizliğinden çöküyor. Bu sorunların büyük çoğunluğunun arkasında yanlış yapılandırılmış php.ini ayarları yatıyor. Sistem yöneticisi olarak PHP’nin bellek ve upload ayarlarını doğru yapılandırmak, hem uygulama stabilitesi hem de güvenlik açısından kritik öneme sahip. Bu yazıda bu ayarları derinlemesine inceleyeceğiz.

php.ini Nedir ve Nerede Bulunur?

PHP’nin ana yapılandırma dosyası olan php.ini, PHP motorunun nasıl çalışacağını belirleyen direktifleri içerir. Sunucunuzda birden fazla php.ini dosyası olabilir; CLI için ayrı, FPM için ayrı, Apache modülü için ayrı dosyalar kullanılır.

Aktif php.ini dosyasının nerede olduğunu bulmak için:

# CLI üzerinden
php --ini

# Web sunucusu üzerinden phpinfo() çıktısına bak
php -r "echo php_ini_loaded_file();"

# PHP-FPM kullanıyorsan
php-fpm8.2 --ini

# Ubuntu/Debian sistemlerde yaygın konumlar
ls /etc/php/8.2/fpm/php.ini
ls /etc/php/8.2/cli/php.ini
ls /etc/php/8.2/apache2/php.ini

Birden fazla php.ini olduğunda hangisinin uygulandığını karıştırmak çok yaygın bir hatadır. CLI’dan yaptığın değişiklik FPM’i etkilemeyebilir, bunu aklında tut.

Temel Bellek ve Upload Direktifleri

PHP’nin bellek ve dosya yükleme davranışını kontrol eden birkaç kritik direktif var. Bunları tek tek inceleyelim.

memory_limit

PHP’nin tek bir istek sırasında kullanabileceği maksimum RAM miktarını belirler.

  • Varsayılan değer: 128M (PHP 8.x için)
  • Önerilen değer: Uygulamaya göre değişir, WordPress için genellikle 256M yeterli
  • -1 değeri: Sınırsız anlamına gelir, production’da dikkatli kullan

Yetersiz bellek sınırı şu hataya yol açar:

Fatal error: Allowed memory size of 134217728 bytes exhausted

upload_max_filesize

Tek bir dosya yüklemesi için izin verilen maksimum boyutu belirler.

  • Varsayılan değer: 2M
  • Önerilen değer: Uygulamanın ihtiyacına göre, genellikle 20M-100M arası

post_max_size

Tüm POST verisi için maksimum boyutu belirler. Dosya yüklemelerini de kapsadığı için her zaman upload_max_filesize değerinden büyük olmalıdır.

  • Varsayılan değer: 8M
  • Kural: post_max_size >= upload_max_filesize + form verileri

max_file_uploads

Tek bir HTTP isteğinde aynı anda yüklenebilecek dosya sayısını sınırlar.

  • Varsayılan değer: 20
  • Güvenlik notu: İhtiyaç olmadan artırma

max_execution_time

PHP betiğinin çalışabileceği maksimum süreyi saniye cinsinden belirtir. Büyük dosya yüklemelerinde bu değerin de artırılması gerekebilir.

  • Varsayılan değer: 30

max_input_time

PHP’nin POST, GET ve dosya yüklemesi gibi giriş verilerini parse etmesi için tanınan maksimum süre.

  • Varsayılan değer: 60
  • Önemli: Büyük dosya yüklemelerinde bu değeri de artırman gerekir

Ayarları Değiştirme Yöntemleri

PHP ayarlarını değiştirmenin birden fazla yolu var. Her birinin farklı bir öncelik sırası ve kullanım senaryosu mevcut.

1. php.ini Dosyasını Doğrudan Düzenlemek

En kalıcı ve güvenilir yöntem budur.

# PHP-FPM için (Nginx ile kullanılan)
sudo nano /etc/php/8.2/fpm/php.ini

# Değiştirilecek satırlar:
memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 68M
max_execution_time = 120
max_input_time = 120
max_file_uploads = 20

Değişiklikten sonra PHP-FPM servisini yeniden başlatman gerekiyor:

# PHP-FPM yeniden başlatma
sudo systemctl restart php8.2-fpm

# Apache modülü kullanıyorsan
sudo systemctl restart apache2

# Değişikliğin uygulandığını doğrula
php -r "echo ini_get('memory_limit');"

2. .htaccess ile Değiştirmek (Apache)

Apache + mod_php kullandığında, uygulama dizinine .htaccess dosyası ekleyerek PHP ayarlarını override edebilirsin. Paylaşımlı hosting ortamlarında sıklıkla kullanılır.

# .htaccess dosyasına eklenecekler
cat >> /var/www/html/myapp/.htaccess << 'EOF'
php_value memory_limit 256M
php_value upload_max_filesize 64M
php_value post_max_size 68M
php_value max_execution_time 120
php_value max_input_time 120
EOF

3. PHP-FPM Pool Yapılandırması

PHP-FPM kullanıyorsan, her pool için ayrı PHP ayarları tanımlayabilirsin. Bu özellikle birden fazla uygulamayı aynı sunucuda barındırırken çok işe yarar.

# Pool yapılandırma dosyasını düzenle
sudo nano /etc/php/8.2/fpm/pool.d/myapp.conf
[myapp]
user = www-data
group = www-data
listen = /run/php/php8.2-fpm-myapp.sock
listen.owner = www-data
listen.group = www-data

pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5

; PHP direktiflerini burada override et
php_admin_value[memory_limit] = 512M
php_admin_value[upload_max_filesize] = 100M
php_admin_value[post_max_size] = 105M
php_admin_value[max_execution_time] = 300
php_admin_flag[log_errors] = on
php_admin_value[error_log] = /var/log/php/myapp-error.log

php_admin_value kullandığında uygulama kodu veya .htaccess bu değeri override edemez, bu güvenlik açısından önemli.

4. Runtime’da ini_set() Kullanmak

Belirli direktifler PHP kodunun içinden de değiştirilebilir, ancak güvenlik açısından kısıtlamaları var.

# PHP kodu içinde (örnek gösterim amaçlı)
php -r "
ini_set('memory_limit', '512M');
echo ini_get('memory_limit');
"

memory_limit runtime’da artırılabilir ama upload_max_filesize ve post_max_size runtime’da değiştirilemez, çünkü bu değerler dosya yükleme işlemi başlamadan önce PHP tarafından okunur.

Gerçek Dünya Senaryosu 1: WordPress Medya Yükleme Sorunu

Bir müşterinin WordPress sitesine büyük görseller yüklenemiyor. Yönetim panelinde şu hata çıkıyor: “HTTP error” veya “Dosya çok büyük.”

# Mevcut ayarları kontrol et
php -r "
echo 'memory_limit: ' . ini_get('memory_limit') . PHP_EOL;
echo 'upload_max_filesize: ' . ini_get('upload_max_filesize') . PHP_EOL;
echo 'post_max_size: ' . ini_get('post_max_size') . PHP_EOL;
echo 'max_execution_time: ' . ini_get('max_execution_time') . PHP_EOL;
"

# PHP-FPM log dosyalarını incele
sudo tail -f /var/log/php8.2-fpm.log
sudo tail -f /var/log/nginx/error.log

Sorunu çözmek için:

# /etc/php/8.2/fpm/php.ini dosyasını düzenle
sudo sed -i 's/memory_limit = 128M/memory_limit = 256M/' /etc/php/8.2/fpm/php.ini
sudo sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 64M/' /etc/php/8.2/fpm/php.ini
sudo sed -i 's/post_max_size = 8M/post_max_size = 70M/' /etc/php/8.2/fpm/php.ini

# Değişiklikleri doğrula
grep -E "memory_limit|upload_max_filesize|post_max_size" /etc/php/8.2/fpm/php.ini

# Nginx için client_max_body_size da ayarlanmalı!
sudo nano /etc/nginx/sites-available/mywordpress.conf

Nginx’te de şu direktifi eklemeyi unutma, yoksa Nginx dosyayı PHP’ye ulaşmadan keser:

server {
    listen 80;
    server_name example.com;
    
    # PHP'nin upload limitiyle eşleşmeli veya daha büyük olmalı
    client_max_body_size 70M;
    
    location ~ .php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_read_timeout 120;
        include fastcgi_params;
    }
}

Gerçek Dünya Senaryosu 2: Birden Fazla Uygulama, Farklı Limitler

Aynı sunucuda hem bir e-ticaret sitesi hem de basit bir blog çalıştırıyorsun. E-ticaret sitesi ürün görselleri için 100MB upload istiyor, blog için 10MB yeterli.

# E-ticaret için ayrı bir FPM pool oluştur
sudo cp /etc/php/8.2/fpm/pool.d/www.conf /etc/php/8.2/fpm/pool.d/ecommerce.conf
sudo nano /etc/php/8.2/fpm/pool.d/ecommerce.conf
[ecommerce]
user = ecommerce_user
group = ecommerce_user
listen = /run/php/php8.2-fpm-ecommerce.sock

pm = dynamic
pm.max_children = 15
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6

php_admin_value[memory_limit] = 512M
php_admin_value[upload_max_filesize] = 100M
php_admin_value[post_max_size] = 105M
php_admin_value[max_execution_time] = 300
php_admin_value[max_input_time] = 300
# Blog için ayrı pool
sudo cp /etc/php/8.2/fpm/pool.d/www.conf /etc/php/8.2/fpm/pool.d/blog.conf
sudo nano /etc/php/8.2/fpm/pool.d/blog.conf
[blog]
user = blog_user
group = blog_user
listen = /run/php/php8.2-fpm-blog.sock

pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

php_admin_value[memory_limit] = 128M
php_admin_value[upload_max_filesize] = 10M
php_admin_value[post_max_size] = 12M
php_admin_value[max_execution_time] = 60

Her pool için ayrı Nginx server block’unda ilgili socket’i belirt:

# E-ticaret sitesi nginx config
location ~ .php$ {
    fastcgi_pass unix:/run/php/php8.2-fpm-ecommerce.sock;
    fastcgi_read_timeout 300;
    include fastcgi_params;
}

# FPM'i yeniden başlat
sudo systemctl restart php8.2-fpm
sudo systemctl status php8.2-fpm

Güvenlik Konuları

Bellek ve upload limitlerini körü körüne artırmak ciddi güvenlik ve performans sorunlarına yol açabilir.

  • memory_limit = -1 kullanma: Kötü yazılmış bir betik sunucu RAM’ini tamamen tüketebilir ve sistemi çökertebilir. Bunun yerine mantıklı bir üst limit koy.
  • upload_max_filesize’ı gereksiz artırma: Büyük dosya yüklemelerine izin vermek disk dolmasına ve DDoS saldırısına zemin hazırlar.
  • Dosya tipi kontrolü: Upload boyutunu artırdıktan sonra uygulama katmanında da MIME type ve dosya uzantısı kontrolü yaptığından emin ol.
  • tmp dizinini izle: PHP upload’ları önce /tmp dizinine yazar. Bu dizinin dolup dolmadığını izle.
# Upload temp dizinini kontrol et
php -r "echo sys_get_temp_dir();"

# Disk kullanımını izle
df -h /tmp

# PHP error log'larını düzenli tara
sudo tail -100 /var/log/php8.2-fpm.log | grep -i "memory|upload|size"

Ayarların Öncelik Sırası

Hangi ayarın geçerli olacağını anlamak için öncelik sırasını bilmek gerekiyor, yüksekten düşüğe:

  • php_admin_value (FPM pool): En yüksek öncelik, uygulama kodundan override edilemez
  • php.ini: Sistem geneli varsayılan
  • .htaccess (php_value): Sadece Apache + mod_php’de geçerli, uygulama kodundan override edilebilir
  • ini_set() (uygulama kodu): En düşük öncelik, runtime’da değiştirilebilir direktifler için geçerli

Değişiklikleri Doğrulama ve Test Etme

Ayar değişikliğinin gerçekten uygulandığını doğrulamak çok önemli. Özellikle CLI ile FPM ortamlarını karıştırmak yaygın bir hata.

# CLI ortamını test et
php -r "
echo 'PHP Sürümü: ' . PHP_VERSION . PHP_EOL;
echo 'memory_limit: ' . ini_get('memory_limit') . PHP_EOL;
echo 'upload_max_filesize: ' . ini_get('upload_max_filesize') . PHP_EOL;
echo 'post_max_size: ' . ini_get('post_max_size') . PHP_EOL;
echo 'max_execution_time: ' . ini_get('max_execution_time') . PHP_EOL;
echo 'max_input_time: ' . ini_get('max_input_time') . PHP_EOL;
echo 'max_file_uploads: ' . ini_get('max_file_uploads') . PHP_EOL;
"

# Web ortamını test etmek için geçici phpinfo dosyası oluştur
# DİKKAT: Testi bitince bu dosyayı hemen sil!
echo "<?php phpinfo();" | sudo tee /var/www/html/temp_phpinfo.php
# Test ettikten sonra:
sudo rm /var/www/html/temp_phpinfo.php

# FPM process'lerini kontrol et
sudo systemctl status php8.2-fpm
sudo php-fpm8.2 -t  # Syntax kontrolü

Uygulama Bazlı Önerilen Değerler

Farklı uygulama türleri için genel kabul görmüş değerleri şöyle özetleyebilirim:

Basit blog / haber sitesi:

  • memory_limit: 128M
  • upload_max_filesize: 10M
  • post_max_size: 12M
  • max_execution_time: 60

WordPress / CMS:

  • memory_limit: 256M (WooCommerce için 512M)
  • upload_max_filesize: 64M
  • post_max_size: 68M
  • max_execution_time: 120

E-ticaret / Büyük dosya yönetim uygulaması:

  • memory_limit: 512M
  • upload_max_filesize: 256M
  • post_max_size: 260M
  • max_execution_time: 300

API backend (dosya yüklemesi yok):

  • memory_limit: 128M
  • upload_max_filesize: 2M (varsayılan yeterli)
  • post_max_size: 8M (varsayılan yeterli)
  • max_execution_time: 30

Sonuç

php.ini ayarları, ilk bakışta basit görünen ama yanlış yapılandırıldığında ciddi sorunlara yol açan bir alan. En kritik nokta şu: post_max_size her zaman upload_max_filesize‘dan büyük olmalı ve Nginx kullanıyorsan client_max_body_size‘ı da güncellemeyi unutmamalısın. Bu iki hatayı yapmayan sistem yöneticisi sayısı şaşırtıcı derecede az.

PHP-FPM pool başına ayrı ayarlar tanımlamak, birden fazla uygulama barındıran sunucularda hem güvenlik hem de kaynak yönetimi açısından en doğru yaklaşım. php_admin_value kullanarak uygulama kodunun bu değerleri aşmasının önüne geçebilirsin.

Son olarak, herhangi bir değişiklik yapmanın ardından mutlaka php-fpm8.2 -t ile syntax kontrolü yap, servisi yeniden başlat ve gerçekten web ortamında değişikliğin uygulandığını doğrula. CLI’dan yaptığın test yeterli değil; FPM ve CLI farklı konfigürasyon dosyaları kullanıyor.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir