---
title: Oturumlar
source: 'https://academia.sh/tr/kurslar/php-web/oturumlar'
course: 'Web ile PHP: Oturum, Veri ve Güvenlik'
language: tr
updated: '2026-10-21T05:03:38+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Oturum çerezinin yalnız bir kimlik taşıdığını, durumun sunucuda kaldığını açıklar'
    - 'session_start() ve $_SESSION ile sepeti sunucuda tutup istemcinin çerezinin sonucu değiştirmediğini ölçer'
    - 'Girişte session_regenerate_id(true) ile kimliği yenileyip oturum verisinin korunduğunu gösterir'
    - 'İstemcinin kimliği seçebildiği sınırı ölçüp oturumu sunucu olarak sınıflayan cümleyi bu sınırla birlikte okur'
---

# Oturumlar

Durumu sunucuda tutan oturum düzeneği: oturum çerezindeki kimlik, $_SESSION, session_regenerate_id(true) ve kimliği taşıyan tarafın sınırı.

Çerezler dersi sepeti istemcide bıraktı ve istemci onu `2`'den `5`'e çevirebildi. İmza bu çevirmeyi fark etti ama sonucun sahibini değiştirmedi. Bu ders aynı değeri sunucuya taşır: istemcinin elinde yalnız bir kimlik kalır, sepetin kendisi sunucuda durur.

Düzeneğin adı **oturum**dur (session). `session_start()` çağrısı iki iş yapar. İstekte bir **oturum kimliği** (session id) taşıyan çerez varsa sunucudaki o kimliğe ait kaydı açar ve içeriğini `$_SESSION` dizisine yükler. Yoksa yeni bir kimlik üretir, boş bir kayıt açar ve kimliği yanıtta bir çerezle, yani **oturum çerezi** (session cookie) olarak yollar. İstemci sonraki isteklerde bu çerezi geri gönderir. Çerezin taşıdığı şey sepet değil, kaydın adıdır.

Kimlik bir tutamaçtır. C'de Bellek ve İşaretçiler kursunda bir işaretçi başka bir yerde duran veriyi gösterir ve gösterdiği şeyin yaşamını kodu yazan yönetir. Oturum kimliği de sunucudaki bir durumu gösteren tutamaçtır; fark, tutamacı elinde taşıyanın kodu yazan değil, istemci olmasıdır. Bu farkın ölçüm için ne anlama geldiği dersin sonunda görülür.

## Sepet Sunucuda

Ölçüm Çerezler dersindeki aynı çekirdekle yapılır. `taraf.php` bir önceki dersten birebir gelir ve değişmez; burada yalnız yeniden verilir.

```php
<?php
// taraf.php — bu sonucu kim değiştirebiliyor?
declare(strict_types=1);

// Kodun dışındaki taraflar, karar sırasıyla: her istek, her dış çağrı, her dağıtım.
const DIS_TARAFLAR = ['istemci', 'üçüncü taraf', 'ortam'];

/** Sonucu bir kez sapmasız, sonra her dış tarafın sapmasıyla ayrı ayrı hesaplar. */
function sina(callable $sonuc, array $sapmalar): array {
    $taban = $sonuc([]);
    $degisti = [];
    foreach (DIS_TARAFLAR as $taraf) {
        if (array_key_exists($taraf, $sapmalar)) {
            $degisti[$taraf] = $sonuc([$taraf => $sapmalar[$taraf]]) !== $taban;
        }
    }
    return $degisti;
}

/** Sonucu değiştirebilen ilk dış taraf; hiçbiri değiştiremiyorsa sunucu. */
function taraf(array $degisti): string {
    foreach (DIS_TARAFLAR as $t) {
        if ($degisti[$t] ?? false) return $t;
    }
    return 'sunucu';
}

function tarafRaporu(string $ad, callable $sonuc, array $sapmalar): string {
    $degisti = sina($sonuc, $sapmalar);
    $satirlar = [];
    foreach ($degisti as $t => $d) $satirlar[] = $t . ($d ? ' değiştirdi' : ' değiştiremedi');
    $sonTaraf = taraf($degisti);
    echo "$ad → $sonTaraf\n    ", implode(' · ', $satirlar), "\n";
    return $sonTaraf;
}
```

Yeni dosya `oturum.php`'dir. İlk bölüm oturumu kurar. Dört ayar açıkça verilir, çünkü ders çalışma zamanının varsayılanına güvenmez. `session.use_strict_mode` sunucunun tanımadığı bir kimliği kabul etmemesini ister; varsayılanı kapalıdır. `session.cookie_samesite` oturum çerezinin başka bir sitenin isteğiyle gönderilmesini sınırlar; varsayılanı boştur. `session.cookie_httponly` çerezi sayfadaki betikten saklar. `session.save_path` kayıtların yazıldığı yeri geçici dizine bağlar. `ob_start()` çıktıyı tamponlar, çünkü oturum başlıkları ilk çıktıdan önce gönderilmek zorundadır ve tampon bu sırayı koşum boyunca korur.

```php
<?php
// oturum.php — sepet oturumda durur; istemcinin çerezi sonucu değiştiremez
declare(strict_types=1);

require 'taraf.php';

ob_start();
ini_set('session.use_strict_mode', '1');
ini_set('session.cookie_samesite', 'Lax');
ini_set('session.cookie_httponly', '1');
ini_set('session.save_path', sys_get_temp_dir());
session_start();
$_SESSION['sepet'] = 2;

$onceki = session_id();
session_regenerate_id(true);
echo 'kimlik yenilendi: ', session_id() !== $onceki ? 'farklı' : 'aynı', "\n";
echo 'sepet korundu: ', $_SESSION['sepet'], "\n";

tarafRaporu(
    'sepet (oturumda)',
    function (array $s): int {
        if (isset($s['istemci'])) {
            $_COOKIE['sepet'] = $s['istemci'];
        }
        return $_SESSION['sepet'];
    },
    ['istemci' => '5'],
);
ob_end_flush();
```

```
kimlik yenilendi: farklı
sepet korundu: 2
sepet (oturumda) → sunucu
    istemci değiştiremedi
```

Sonuç bölümü iki işi bir arada gösterir. İlk iki satır girişte yapılan kimlik yenilemesidir; sonraki iki satır ölçümdür. Ölçümde istemci `sepet=5` gönderir ve sapma bunu `$_COOKIE`'ye yazar. Sepeti okuyan kod ise `$_SESSION['sepet']`'e bakar. Çerez değişir, sonuç değişmez.

**DO5.** Karar sırası istemci, üçüncü taraf, ortam, sunucudur. Bu ölçümün karşıtı Çerezler dersindeki ilk satırdır: orada aynı sapma aynı sepeti `2`'den `5`'e çevirdi ve sonuç **istemci** çıktı. Burada aynı sapma sonucu değiştiremedi ve sonuç **sunucu**dur. Fark değerin taşındığı yerdir: sepet çerezdeyken isteği gönderen sepetin sahibiydi, sepet sunucudaki kayıtta durunca onun elinde yalnız kaydın adı kalır.

## Kaydın Ömrü ve Bedeli

Sunucuda durmanın iki bedeli vardır. Birincisi ömürdür. Kayıt, kullanıcı çıkış yapınca ya da süresi dolunca silinmelidir; silinmezse sunucuda kimsenin kullanmadığı kayıtlar birikir. Kayıt silindiğinde istemcinin elindeki kimlik geçersiz kalır ve `session.use_strict_mode` açıkken sunucu onu kabul etmez, yeni bir kimlik üretir. Kimliğin istemcide kalması, kaydın sunucuda yaşamasını garanti etmez; kaydın yaşadığına sunucu karar verir.

İkincisi ölçeklemedir. Kayıtlar tek bir makinenin geçici dizininde duruyorsa, aynı kullanıcının iki isteği iki farklı makineye düştüğünde ikinci makine kaydı bulamaz. Bu yüzden birden çok makine çalışan bir uygulamada kayıtlar paylaşılan bir depoya yazılır. Bu bir yapılandırma kararıdır ve bir sonraki dersin konusuna yaklaşır: depoyu kodun içine yazmak yerine ortamın seçmesi gerekir.

Sunucuda durmak bir şeyi daha değiştirir: sepetin doğruluğu artık istemcinin dürüstlüğüne bağlı değildir. Çerezde `5` gelen bir sepeti sunucunun gerçekten `5` olduğunu doğrulaması gerekirdi; oturumda doğrulanacak bir şey yoktur, çünkü değeri sunucu yazdı. Doğrulama yükü kalkmaz, yer değiştirir: kimliğin geçerliliği, kaydın var olup olmadığına indirgenir ve bunu `session_start()` kendi başına yapar.

## Kimliği Yenilemek

Kimlik girişten önce ve sonra aynı kalırsa kimliği bilen biri giriş yapmış oturumu da bilir. Buna **oturum sabitleme** (session fixation) denir. Düzenek basittir: kullanıcı doğrulandığı anda `session_regenerate_id(true)` çağrılır. Fonksiyon yeni bir kimlik üretir, `true` argümanı eski kimliğe ait kaydı siler ve `$_SESSION` içeriği yeni kayda taşınır.

Ölçüm bunu iki satırda gösterir: kimlik yenilendikten sonra öncekinden **farklı**dır ve `sepet` `2` olarak korunur. Kimliğin kendisi basılmaz, çünkü her koşumda değişir; ölçülen şey farktır. Sabitleme saldırısı bu derste kurulmaz. Düzeneğin işi o saldırının dayandığı varsayımı, giriş öncesi ve sonrası kimliğin aynı kalmasını ortadan kaldırmaktır.

**DO6.** `session_regenerate_id(true)` sunucunun kendi kaydını güvenceye alan bir önlemdir ve taraf cümlesini değiştirmez. Kimliği üreten de, yenileyen de, eski kaydı silen de sunucudur. Ama kimliği yanıtta çerezle istemciye geri yollamak yine istemcide durmak zorundadır; bu iki durumun birleşimi bir sonraki bölümün konusudur.

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

Oturumun sahibi sunucu olarak sınıflandı. Bu cümlenin bir sınırı var: oturum kimliğinin kendisi istemcidedir. İstemci çerezde başka bir kimlik sunarsa ne olur? Aşağıdaki dosya önce bir oturum açıp sepeti `2` yapar, sonra aynı sepeti iki kimlikle okur: sunucunun verdiği kimlik ve istemcinin sunduğu başka bir kimlik. Başka kimlik, sunucunun hiç üretmediği nötr bir dizgedir.

```php
<?php
// baska.php — istemci başka bir oturum kimliği sunarsa hangi oturuma düşer
declare(strict_types=1);

require 'taraf.php';

ob_start();
ini_set('session.use_strict_mode', '1');
ini_set('session.cookie_samesite', 'Lax');
ini_set('session.cookie_httponly', '1');
ini_set('session.save_path', sys_get_temp_dir());

function sepetOku(string $kimlik): int
{
    session_id($kimlik);
    session_start();
    $sepet = $_SESSION['sepet'] ?? 0;
    session_write_close();
    return $sepet;
}

session_start();
$_SESSION['sepet'] = 2;
$kimlik = session_id();
session_write_close();

tarafRaporu(
    'sepet (oturumda, istemci başka kimlik sunar)',
    fn(array $s) => sepetOku($s['istemci'] ?? $kimlik),
    ['istemci' => 'baskakimlik0123456789'],
);
ob_end_flush();
```

```
sepet (oturumda, istemci başka kimlik sunar) → istemci
    istemci değiştirdi
```

**DO7.** Sonuç değişti ve değiştiren **istemci**dir. Sunucu tanımadığı kimliği kabul etmedi (`session.use_strict_mode`) ve yeni, boş bir kayıt açtı; sepet `2` yerine `0` okundu. İstemci kendi sepetine başka bir kimlikle değil, hiçbir sepeti olmayan bir oturuma düştü.

Ölçümün ikinci bir okuması da vardır: sapma sunucunun kaydını değiştirmedi. Sunucudaki oturum `2` olarak kaldı, değişen hangi oturumun açıldığıdır. Karar sırası bu yüzden tek bir ölçümde iki cümleye bölünür: sepetin içeriğini istemci belirleyemez, hangi sepetin açılacağını istemci belirler.

## Özet

- Oturum, durumu sunucuda tutar. İstemcide kalan yalnız bir kimliktir ve oturum çerezi bunu her istekle geri taşır.
- `session_start()` kimlik varsa kaydı açıp `$_SESSION`'a yükler, yoksa yeni bir kimlik ve boş kayıt üretir.
- Aynı `sepet=5` sapması Çerezler dersinde sonucu değiştirdi; oturumda değiştiremedi. Bu dersin ölçü sınıfı **sunucu**dur: sepetin içeriğini istemci belirleyemez.
- `session_regenerate_id(true)` girişte kimliği yeniler, eski kaydı siler ve `$_SESSION` içeriğini korur; sabitlemeye karşı düzenek budur.
- Sınır: kimliği taşıyan istemcidir. İstemci başka bir kimlik sunarsa kendi sepetine değil başka bir oturuma düşer, yani hangi oturumun açılacağı istemcide kalır.

## Sonraki Adım

Çerez de, oturum da istekle gelen veriyi ölçtü. Bir uygulamanın okuduğu her değer istekten gelmez: veritabanı adı, anahtar ve bağlantı ayarları dağıtım ortamından gelir. Sonraki ders, Yapılandırma ve Ortam Değişkenleri, bu değerleri koddan ayırıp ortama bırakır ve kimin değiştirebildiğini ölçer.
