---
title: 'Yapılandırma Ayarı'
source: 'https://academia.sh/tr/kurslar/php-uretim/yapilandirma-ayari'
course: "PHP'de Kalite, Başarım ve Dağıtım"
language: tr
updated: '2026-10-21T05:03:36+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Geliştirme ve üretim ayar dosyalarını ayıran yedi yönergeyi ve her birinin değerini sıralayabilmek'
    - 'Çalışırken zend.assertions değerinin üretimde değiştirilemediğini ve istisna izinde argümanların gizlendiğini ölçmek'
    - 'Kod içinden ini_set() ile display_errors açmanın sertleştirmeyi geri alabileceğini yorumlamak'
---

# Yapılandırma Ayarı

PHP'nin geliştirme ve üretim ayar dosyalarının ayrıştığı yedi yönergeyi ölçmek: sertleştirme neyi kapatır ve kod içinden ini_set() ile geri açılabilir mi.

PHP iki hazır ayar dosyasıyla dağıtılır: biri geliştirme, biri üretim içindir. Bu dersin konusu, o iki dosyanın birbirinden hangi noktada ayrıldığıdır. Ayrım bir tercih listesi değil, sertleştirmedir (hardening): üretimde hata ayrıntısını, çağrı argümanlarını ve geliştirme denetimlerini kapatarak, bir hatanın dışarıya bilgi sızdırmasını engellemek. Ortam değişkenleriyle yapılandırmayı daha önce web uygulaması bağlamında gördünüz ("Yapılandırma ve Ortam Değişkenleri"); burada ayarın kendisi, yani PHP'nin yönergeleri ölçülür.

Ölçü ekseni bu kursun ortak sorusudur: bu davranış üretime çıkıyor mu? Aşağıdaki `yan.php` tam olarak bu iki dosyayı `PROFILLER` sabitinde taşır. Dosya bu derste de yalnız diske yazılır.

```php
<?php
// yan.php — bu davranış üretime çıkıyor mu?
declare(strict_types=1);

// PHP'nin dağıttığı iki ayar dosyası (php.ini-development, php.ini-production) yedi
// yönergede ayrışır; yedisi buraya birebir alındı. Üretimdeki son iki satır dağıtım
// dosyasında yorum satırıdır: kod önbelleği komut satırında da açık, dosya denetimi kapalı.
const PROFILLER = [
    'geliştirme' => [
        'display_errors' => '1',
        'display_startup_errors' => '1',
        'error_reporting' => '32767',
        'mysqlnd.collect_memory_statistics' => '1',
        'zend.assertions' => '1',
        'zend.exception_ignore_args' => '0',
        'zend.exception_string_param_max_len' => '15',
    ],
    'üretim' => [
        'display_errors' => '0',
        'display_startup_errors' => '0',
        'error_reporting' => '24575',
        'mysqlnd.collect_memory_statistics' => '0',
        'zend.assertions' => '-1',
        'zend.exception_ignore_args' => '1',
        'zend.exception_string_param_max_len' => '0',
        'opcache.enable_cli' => '1',
        'opcache.validate_timestamps' => '0',
    ],
];

/** Betiği ayar dosyası olmadan, yalnız profilin yönergeleriyle ayrı bir süreçte koşturur. */
function calistir(string $betik, array $yonergeler): bool {
    $komut = ['php', '-n'];
    foreach ($yonergeler as $ad => $deger) {
        array_push($komut, '-d', "$ad=$deger");
    }
    $komut[] = $betik;
    $surec = proc_open($komut, [1 => ['pipe', 'w'], 2 => ['file', '/dev/null', 'w']], $borular);
    $cikti = stream_get_contents($borular[1]);
    fclose($borular[1]);
    proc_close($surec);
    $satirlar = array_values(array_filter(array_map('trim', explode("\n", $cikti))));
    return end($satirlar) === 'evet';
}

/** Davranışın iki koşumda görülüp görülmediğinden yanını çıkarır. */
function yan(bool $gelistirmede, bool $uretimde): string {
    return match (true) {
        $gelistirmede && $uretimde => 'iki yanda da',
        $gelistirmede => 'yalnız geliştirmede',
        $uretimde => 'yalnız üretimde',
        default => 'koşuma girmiyor',
    };
}

function yanRaporu(string $ad, string $betik): string {
    $gelistirmede = calistir($betik, PROFILLER['geliştirme']);
    $uretimde = calistir($betik, PROFILLER['üretim']);
    $sonYan = yan($gelistirmede, $uretimde);
    echo "$ad → $sonYan\n    geliştirme ", $gelistirmede ? 'evet' : 'hayır',
        ' · üretim ', $uretimde ? 'evet' : 'hayır', "\n";
    return $sonYan;
}
```

Önce yedi farkı `PROFILLER` sabitinden çıkaralım. Betik iki profildeki değerleri karşılaştırır ve yalnız ayrışan yönergeleri yazar. Profil dizisinde yalnız üretime özgü olan `opcache.*` yönergeleri bu karşılaştırmanın dışında kalır, çünkü iki dosyanın farkı değil, komut satırında kod önbelleğini açan eklemelerdir.

```php
<?php
// fark.php — iki profilin ayrıştığı yönergeleri yazar
declare(strict_types=1);
require __DIR__ . '/yan.php';

$ayrisan = 0;
foreach (PROFILLER['geliştirme'] as $ad => $deger) {
    $uretim = PROFILLER['üretim'][$ad];
    if ($deger !== $uretim) {
        $ayrisan++;
        echo "$ad: geliştirme $deger · üretim $uretim\n";
    }
}
echo "ayrışan yönerge sayısı: $ayrisan\n";
```

```
display_errors: geliştirme 1 · üretim 0
display_startup_errors: geliştirme 1 · üretim 0
error_reporting: geliştirme 32767 · üretim 24575
mysqlnd.collect_memory_statistics: geliştirme 1 · üretim 0
zend.assertions: geliştirme 1 · üretim -1
zend.exception_ignore_args: geliştirme 0 · üretim 1
zend.exception_string_param_max_len: geliştirme 15 · üretim 0
ayrışan yönerge sayısı: 7
```

Yedi satırın okunuşu şöyledir. İlk üç satır hata görünürlüğünü belirler: `display_errors` ve `display_startup_errors` hatayı yanıta yazar, `error_reporting` hangi türlerin bildirileceğini söyler. `mysqlnd.collect_memory_statistics` veritabanı sürücüsünün bellek istatistiğini toplar, üretimde kapalıdır. `zend.assertions` `assert()` çağrılarının derlenip derlenmeyeceğini belirler. Son iki satır istisna izine aittir: `zend.exception_ignore_args` izden çağrı argümanlarını atar, `zend.exception_string_param_max_len` kalan dize argümanlarının uzunluğunu sınırlar.

| Yönerge | Geliştirme | Üretim |
|---|---|---|
| `display_errors` | `1` | `0` |
| `display_startup_errors` | `1` | `0` |
| `error_reporting` | `32767` | `24575` |
| `mysqlnd.collect_memory_statistics` | `1` | `0` |
| `zend.assertions` | `1` | `-1` |
| `zend.exception_ignore_args` | `0` | `1` |
| `zend.exception_string_param_max_len` | `15` | `0` |

Şimdi ayrımın davranışa nasıl yansıdığına bakalım. Birinci yoklama çalışırken `ini_set('zend.assertions', '1')` dener ve çağrının reddedildiğini, değerin değişmediğini sorar. İkinci yoklama içinde bir fonksiyon çağrısı olan bir istisna fırlatır ve istisna izinde argümanın saklanıp saklanmadığına bakar. Her iki yoklama da `evet` yönünde yazıldı: yalnız üretimde görünen davranış `evet` verir.

```php
<?php
// ayar.php — sertleştirme davranışta nasıl görünür?
declare(strict_types=1);
require __DIR__ . '/yan.php';

file_put_contents('assertion.php', <<<'PHP'
<?php
// assertion.php — çalışırken zend.assertions açılmaya çalışılır
$donen = @ini_set('zend.assertions', '1');
echo $donen === false && ini_get('zend.assertions') === '-1' ? "evet\n" : "hayır\n";
PHP);

file_put_contents('iz.php', <<<'PHP'
<?php
// iz.php — istisna izinde çağrı argümanı saklanır mı?
function at(string $gizli): void {
    throw new RuntimeException();
}
try {
    at('gizli deger');
} catch (RuntimeException $istisna) {
    echo !isset($istisna->getTrace()[0]['args']) ? "evet\n" : "hayır\n";
}
PHP);

yanRaporu('zend.assertions çalışırken açılamaz', 'assertion.php');
yanRaporu('istisna izinde argüman saklanmaz', 'iz.php');
```

```
zend.assertions çalışırken açılamaz → yalnız üretimde
    geliştirme hayır · üretim evet
istisna izinde argüman saklanmaz → yalnız üretimde
    geliştirme hayır · üretim evet
```

Her iki yoklama yalnız üretimde `evet` verdi: yan **yalnız üretimde**. Üretimde `zend.assertions` değeri `-1` iken çalışırken açılmaya çalışılan değer reddedildi ve `-1` kaldı; bu, üretimde derlenmemiş `assert()` çağrılarının sonradan etkinleştirilemeyeceği anlamına gelir. İstisna izi ise argümanı taşımadı; geliştirmede aynı iz argümanı taşıdığı için bir hata mesajının yığıt kaydı bir parolayı ya da kullanıcı verisini dışarı çıkarabilirdi. Üretimde bu iki sızıntı yolu kapalıdır. (**BA5.** Bu yoklama yalnız profil değerinin etkisine bakar; `zend.exception_ignore_args` yönergesinin çalışırken değiştirilebilirliği aşağıdaki erişim düzeyi bölümünde ölçülür.)

## Yönergenin Erişim Düzeyi

Ayar dosyası bir yönergeyi belirler, ama yönergeye sonradan kim dokunabilir sorusu ayrıdır. PHP her yönergeye bir erişim düzeyi (access level) verir: `PHP_INI_USER` kullanıcı betiğinin `ini_set()` ile değiştirebileceği, `PHP_INI_PERDIR` ayar dosyasında ya da dizin düzeyinde değiştirilebileni, `PHP_INI_SYSTEM` ise yalnız ana ayar dosyasında belirlenebileni gösterir. Üçünü birden taşıyan yönerge `PHP_INI_ALL` olarak anılır. `ini_get_all(null, true)` her yönergenin bu düzeyini döndürür. Aşağıdaki yoklama sekiz yönerge için iki şey yazar: erişim düzeyi ve `ini_set()` çağrısının kabul edilip edilmediği. Kabul, çağrının `false` dönmemesi demektir. Sekiz yönergeden yedisi profil farkı olan yönergelerdir; sekizincisi `opcache.enable_cli` üretim profilinin eklediği ve değeri komut satırında kod önbelleğini açan yönergedir. `mysqlnd.collect_memory_statistics` ölçüm dışında bırakıldı: yönerge veritabanı sürücüsü eklentisine bağlıdır ve bu ders yalnız çekirdek ve kod önbelleği yönergelerinin erişim düzeyini ölçer. Yoklama çocuk süreçte koşar, sonucu profile özgü dosyaya yazar; sürücü ikisini karşılaştırır.

Ek olarak ikinci bir yoklama, `zend.exception_ignore_args` için `ini_set()` davranışını doğrudan sınar: üretim profilinde yönerge `1` iken kod içinden `0` yapılırsa, sonradan fırlatılan istisnanın izinde argüman görünür mü?

```php
<?php
// erisim.php — yönergeyi kim değiştirebilir, ini_set() kabul eder mi?
declare(strict_types=1);
require __DIR__ . '/yan.php';

file_put_contents('erisim-olc.php', <<<'PHP'
<?php
// erisim-olc.php — erişim düzeyini ve ini_set() kabulünü profile özgü dosyaya yazar
$profil = ini_get('zend.assertions') === '1' ? 'gelistirme' : 'uretim';
$hedefler = [
    'display_errors' => '1',
    'display_startup_errors' => '1',
    'error_reporting' => '1',
    'zend.assertions' => '0',
    'zend.exception_ignore_args' => '0',
    'zend.exception_string_param_max_len' => '5',
    'opcache.enable_cli' => '1',
    'opcache.validate_timestamps' => '1',
];
$tum = ini_get_all(null, true);
$seviyeler = [1 => 'USER', 2 => 'PERDIR', 4 => 'SYSTEM'];
$satirlar = [];
foreach ($hedefler as $ad => $hedef) {
    $erisim = $tum[$ad]['access'];
    $adlar = [];
    foreach ($seviyeler as $bit => $seviye) {
        if (($erisim & $bit) !== 0) {
            $adlar[] = $seviye;
        }
    }
    $kabul = @ini_set($ad, $hedef) !== false ? 'kabul' : 'ret';
    $satirlar[] = $ad . ': ' . ($erisim === 7 ? 'ALL' : implode('|', $adlar)) . ' · ini_set ' . $kabul;
}
file_put_contents("erisim-$profil.txt", implode("\n", $satirlar) . "\n");
echo "evet\n";
PHP);

file_put_contents('iz-acik.php', <<<'PHP'
<?php
// iz-acik.php — zend.exception_ignore_args kod içinden 0 yapılırsa izde argüman görünür mü?
ini_set('zend.exception_ignore_args', '0');
function at(string $gizli): void {
    throw new RuntimeException();
}
try {
    at('gizli deger');
} catch (RuntimeException $istisna) {
    echo isset($istisna->getTrace()[0]['args']) ? "evet\n" : "hayır\n";
}
PHP);

yanRaporu('erişim ölçümü tamamlanır', 'erisim-olc.php');
echo file_get_contents('erisim-uretim.txt');
$uretimSatirlari = file('erisim-uretim.txt', FILE_IGNORE_NEW_LINES);
foreach (file('erisim-gelistirme.txt', FILE_IGNORE_NEW_LINES) as $satir) {
    if (!in_array($satir, $uretimSatirlari, true)) {
        echo "geliştirmede farklı: $satir\n";
    }
}
yanRaporu('kod içinden 0 yapılan zend.exception_ignore_args izde argümanı geri getirir', 'iz-acik.php');
```

```
erişim ölçümü tamamlanır → iki yanda da
    geliştirme evet · üretim evet
display_errors: ALL · ini_set kabul
display_startup_errors: ALL · ini_set kabul
error_reporting: ALL · ini_set kabul
zend.assertions: ALL · ini_set ret
zend.exception_ignore_args: ALL · ini_set kabul
zend.exception_string_param_max_len: ALL · ini_set kabul
opcache.enable_cli: SYSTEM · ini_set ret
opcache.validate_timestamps: ALL · ini_set kabul
geliştirmede farklı: zend.assertions: ALL · ini_set kabul
kod içinden 0 yapılan zend.exception_ignore_args izde argümanı geri getirir → iki yanda da
    geliştirme evet · üretim evet
```

Tabloyu satır satır okuyalım. Sekiz yönergenin yedisi `ALL` düzeyindedir; yani `PHP_INI_USER`, `PHP_INI_PERDIR` ve `PHP_INI_SYSTEM` bitlerinin üçü de açıktır ve kod içinden `ini_set()` ile değiştirilebilir. `opcache.enable_cli` ise yalnız `SYSTEM` düzeyindedir: yalnız ana ayar dosyasında ya da komut satırında verilebilir ve çalışırken `ini_set()` onu reddeder. Tablo `ret` ile `kabul` arasındaki farkı gösterir. `ret`, çağrının `false` döndüğü, değerin değişmediği anlamına gelir. `kabul` ise çağrının değeri değiştirdiğidir. Tabloda üretim yanında iki `ret` var: `zend.assertions` ve `opcache.enable_cli`. Geliştirme yanında yalnız biri var: `opcache.enable_cli`.

Üretim ile geliştirme arasındaki tek fark `zend.assertions` satırıdır ve sürücünün son satırı bunu açıkça yazar: geliştirmede aynı yönerge `kabul` verdi. Erişim düzeyi iki profilde de `ALL` görünüyor, yani yönerge kâğıt üzerinde kod içinden değiştirilebilir; yine de üretimde `-1` iken reddediliyor. Bunun sebebi PHP'nin bu yönergeye koyduğu ek kuraldır: `-1` değeri derleme zamanında `assert()` çağrılarının koddan çıkarılması demektir ve bir kez çıkarılan çağrı çalışırken geri getirilemez. Erişim düzeyi tek başına yeterli bilgi vermez: `ALL` yazan bir yönerge yine de belirli bir değerden belirli değerlere geçişi reddedebilir. Bu yüzden ölçüm yalnız tabloya değil, `ini_set()` sonucuna da bakar.

Üretimde altı yönergenin `kabul` çıkması önemli bir uyarıdır: `display_errors`, `error_reporting`, `zend.exception_ignore_args` ve `zend.exception_string_param_max_len` gibi yönergeler ayar dosyasında sertleştirildiği hâlde, kodun herhangi bir satırı bunları gevşetebilir. Son yoklama bunu `zend.exception_ignore_args` için doğrudan gösterdi. Üretim profilinde yönerge `1` iken kod içinden `0` yapıldığında, sonradan fırlatılan istisnanın izinde argüman yeniden göründü. (**BA7.** Yoklama yönergeyi istisna fırlatmadan önce değiştirdi; önceden oluşturulmuş bir istisnanın izi sonradan değişmez, bu ölçülmedi.) Bu yoklama iki profilde de `evet` verdiği için sınıfı `iki yanda da`dır; ama çıkardığı sonuç yalnız üretim için önemlidir, çünkü üretimde bu çağrı sertleştirmeyi geri alır.

Gerçek bir uygulamada bunun karşılığı iki somut alışkanlıktır. Birincisi, kodda `ini_set()` çağrılarını düzenli aramaktır: özellikle kütüphanelerin içinde hata görünürlüğünü ya da istisna izini gevşeten çağrılar, ayar dosyasındaki sertleştirmeyi sessizce geçersiz kılar. İkincisi, bir yönergeyi gerçekten kilitlemek istiyorsanız erişim düzeyine bakmaktır: `PHP_INI_SYSTEM` düzeyindeki yönergeler kod içinden değişmez, `ALL` düzeyindekiler değişir. Bazı barındırma kurulumları `disable_functions` ya da özel ayar dosyalarıyla `ini_set()` çağrısının kendisini kısıtlar; bu kısıtlamalar bu derste kurulmadı ve ölçülmedi.


## Sınırlayıcı Ölçüm

Sertleştirme ayar dosyasında yapılır; kod içinden geri alınamaz mı? `display_errors` bir kod satırıyla yeniden açılabilen yönergelerden biridir. Üretim profiliyle başlayıp betik içinde `ini_set('display_errors', '1')` çağırırsak hata yanıta yazılır mı? Yoklama hata iletisini yakalar ve metnini basmaz; yalnız bir uyarı iletisinin yakalanıp yakalanmadığını söyler.

```php
<?php
// sinir.php — kod içi ini_set() display_errors'u geri açar mı?
declare(strict_types=1);
require __DIR__ . '/yan.php';

file_put_contents('gorunur.php', <<<'PHP'
<?php
// gorunur.php — display_errors kod içinden açılır, uyarı yakalanır
$donen = ini_set('display_errors', '1');
ob_start();
echo $tanimsiz;
$yakalanan = ob_get_clean();
echo $donen !== false && ini_get('display_errors') === '1' && str_contains($yakalanan, 'Warning') ? "evet\n" : "hayır\n";
PHP);

yanRaporu('ini_set() ile açılan display_errors uyarıyı yanıta yazar', 'gorunur.php');
```

```
ini_set() ile açılan display_errors uyarıyı yanıta yazar → iki yanda da
    geliştirme evet · üretim evet
```

Yoklama iki profilde de `evet` verdi: üretim profilinde başlayan süreç, kod içinden `display_errors` açıldığında uyarıyı yanıta yazdı. Yani ayar dosyasındaki `display_errors=0` bir kilit değildir; bir kütüphane ya da bir betik satırı onu geri açabilir. Karşıt örnek `zend.assertions` idi: o yönerge `-1` iken çalışırken açılamaz. Sertleştirmenin gücü yönergeden yönergeye değişir, bu yüzden üretimde yalnız ayar dosyasına güvenmek yetmez. Kodda `ini_set()` çağrılarını aramak ve hata görünürlüğünü bu kayıtların dışında da denetlemek gerekir.

Dersin dürüst sınırı şudur: ölçülen şey yedi yönergenin değerleri ve bu değerlerin yukarıdaki yoklamalarda görülen davranışlarıdır. Bir üretim kurulumunda başka yönergeler de açılır ya da kapanır; liste burada hazır dosyaların farkıdır, bir kurulum kontrol listesi değil.

Dersin ölçümlerini birbirine bağlayalım. Yedi yönergelik fark tablosu, hazır iki dosyanın profile göre nerede ayrıştığını söyler. Davranış yoklamaları, o ayrımın üretimde somut olarak neyi kapattığını gösterir: çalışırken açılamayan `assert()` denetimi ve argümansız istisna izi. Erişim düzeyi ölçümü ise bu kapanışın ne kadar sağlam olduğunu sınar: bazıları kilitlidir, bazıları değildir. Sınırlayıcı ölçüm de aynı soruyu `display_errors` için sorar ve yanıtın olumsuz olduğunu gösterir. Birlikte okununca ortaya şu çıkar: üretim ayarı bir sertleştirme listesidir, ama her maddesinin aynı sağlamlıkta olduğunu varsaymak yanlıştır.

## Özet

- Geliştirme ve üretim ayar dosyaları yedi yönergede ayrışır: `display_errors`, `display_startup_errors`, `error_reporting`, `mysqlnd.collect_memory_statistics`, `zend.assertions`, `zend.exception_ignore_args` ve `zend.exception_string_param_max_len`.
- Bu dersin ölçü sınıfı **yalnız üretimde**dir: üretimde `zend.assertions` çalışırken açılamaz ve istisna izinde argüman saklanmaz; geliştirmede ikisi de görülmez.
- Ayrımın amacı sertleştirmedir: hata ayrıntısı, çağrı argümanları ve geliştirme denetimleri üretimde dışarı sızmaz.
- `display_errors` kod içinden `ini_set()` ile geri açılabildi (iki yanda da); ayar dosyasındaki değer her yönerge için kilit değildir.
- Erişim düzeyi tek başına yetmez: `zend.assertions` `ALL` görünür ama üretimde `-1` iken `ini_set()` reddedilir, geliştirmede kabul edilir; `opcache.enable_cli` her iki profilde de `SYSTEM` düzeyindedir ve reddedilir (ölçü sınıfı: yalnız üretimde).
- Kod içinden `0` yapılan `zend.exception_ignore_args`, üretimde istisna izine argümanı geri getirir (ölçü sınıfı: iki yanda da).

## Sonraki Adım

Bu kursun son dersi dağıtım iş akışıdır: kodu üretime alırken ayar, kod önbelleği ve süreç yöneticisinin tek bir akışta nasıl bir araya geldiği. Önceki beş derste ölçülen her davranış orada bir adıma karşılık gelir.
