# Phalcon’da Karşılaştığım İki Can Sıkıcı Hata ve Çözümleri: e_id ve SoftDelete

> Eğer Phalcon kullanıyorsan, muhtemelen performans ve esneklik açısından ne kadar güçlü olduğunu fark etmişsindir. Ama işte, her güzel şeyin bir bedeli var! Phalcon’un PHQL (Phalcon Query Language) motoru bazen beklenmedik sürprizler yapabiliyor.

- Yazar: [Halit Yeşil](https://halityesil.com/)
- Yayın tarihi: 2025-07-27
- Dil: Türkçe
- Kaynak adres: https://halityesil.com/phalconda-karsilastigim-iki-can-sikici-hata-ve-cozumleri-e-id-ve-softdelete/
- İngilizce sürümü: https://halityesil.com/en/two-annoying-phalcon-errors-and-how-to-fix-them-e-id-and-softdelete.md
- Kategori: Phalcon, Yazılımcılar İçin Hayatta Kalma Kılavuzu
- Etiketler: e_id hatası, hata çözümü, pdo, phalcon, phalcon e_id hatası çözümü, phalcon geliştirici rehberi, phalcon hata ayıklama, phalcon kalıcı silme yöntemi, phalcon model initialize sorunu, phalcon note_id ayrıştırma hatası, phalcon note_id hatası, phalcon pdo ile silme, phalcon phql köşeli parantez, phalcon phql sorgu hatası, phalcon softdelete atlama, phalcon softdelete devre dışı bırakma, phalcon softdelete kalıcı silme, phalcon veritabanı silme sorunu, phalcon veritabanı yönetimi, php framework, phql, softdelete, veritabanı silme
- Lisans: https://creativecommons.org/licenses/by-nc/4.0/
- Atıf: Halit Yeşil. “Phalcon’da Karşılaştığım İki Can Sıkıcı Hata ve Çözümleri: e_id ve SoftDelete”. halityesil.com, 2025-07-27. https://halityesil.com/phalconda-karsilastigim-iki-can-sikici-hata-ve-cozumleri-e-id-ve-softdelete/

---

## Phalcon’da Neler Ters Gidiyor?

Ben de iki can sıkıcı sorunla karşılaştım:

1. **e\_id Hatası**: `note_id` gibi masum bir sütun adını sorguya yazdığında, Phalcon’un bunu `not e_id` gibi ayrıştırıp "Column 'e\_id' doesn't exist" hatası vermesi.
2. **SoftDelete ile Kalıcı Silme Sorunu**: `SoftDelete` davranışını kullanıyorsun, ama bazen kayıtları gerçekten veritabanından silmen gerekiyor. Phalcon, modeli `initialize` edip önbelleğe aldığı için bu davranışı çalışma anında atlamak neredeyse imkânsız.

Bu sorunlar seni de çıldırttı mı? Hadi, çözümleri konuşalım!

## Neden Bu Kadar Sinir Bozucu?

### e\_id Hatası

Diyelim ki `NotesTranslations` modelinde bir sorgu çalıştırıyorsun:

```php
$translation = NotesTranslations::findFirst([
    'conditions' => 'note_id = :noteId:',
    'bind' => ['noteId' => 123]
]);
```

Ve BAM! Karşında şu hata:
`Column 'e_id' doesn't belong to any of the selected models`.
Neden? Çünkü Phalcon’un PHQL motoru, `note_id`’yi ayrıştırırken `not` ifadesini bir operatör sanıyor ve `e_id`’yi bir sütun gibi algılıyor. Tabii ki veritabanında böyle bir sütun yok! Saatlerce debug yap, stack trace’leri tara, ama çözüm internette bile zor bulunuyor. Bu hata, özellikle sütun adlarında `not` gibi kelimeler geçtiğinde seni çaresiz bırakabilir.

### SoftDelete Sorunu

`SoftDelete` davranışıyla çalışırken, `is_deleted` gibi bir sütunu güncelleyerek kayıtları "silmiş" gibi yapıyorsun. Ama bazen, mesela bir test ortamında veya yasal bir gereklilik yüzünden, kayıtları gerçekten silmen gerekiyor. Phalcon’un `modelsManager`’ı, modeli ilk sorguda `initialize` edip önbelleğe alıyor. Bu yüzden `SoftDelete`’i çalışma anında devre dışı bırakmak mümkün değil. Ne denesen olmuyor:

- Statik bir bayrak (`$disableSoftDelete`) ekliyorsun, ama model zaten önbelleğe alınmış.
- Çocuk sınıf oluşturuyorsun, ama Phalcon yine ana sınıfı kullanıyor.
- PHQL ile ham sorgu yazıyorsun, ama yine modelin davranışları devreye giriyor.

Bu durum, projenin ortasında saatlerini yiyebilir ve seni "Neden Phalcon kullanıyorum ki?" diye sorgulamaya itebilir.

## İşte Çözümler!

### 1. e\_id Hatasını Çözme

`e_id` hatasının çözümü basit ama kurnazca: PHQL sorgularında sütun adlarını köşeli parantez (`[]`) ile sar! Bu, Phalcon’un sütun adını yanlış ayrıştırmasını önler. Örneğin:

```php
$translation = NotesTranslations::findFirst([
    'conditions' => '[note_id] = :noteId: AND [language_id] = :languageId:',
    'bind' => [
        'noteId' => 123,
        'languageId' => 1
    ]
]);
```

Bu küçük değişiklik, Phalcon’un `note_id`’yi `not e_id` gibi görmesini engeller. Artık hata yok, sorgu düzgün çalışıyor! Ama dikkat: Bu sadece PHQL sorguları için geçerli. PDO ile ham SQL yazarsan, köşeli parantezlere gerek kalmaz.

**İpucu**: Eğer sütun adlarında `not` gibi başka potansiyel tuzaklar varsa (örneğin, `order_id` veya `set_id`), her zaman `[sütun_adı]` formatını kullan. Böylece Phalcon’un PHQL motorunu kandırmış olursun!

### 2. SoftDelete ile Kalıcı Silme

`SoftDelete` davranışını atlayarak kalıcı silme yapmak için en kesin çözüm, Phalcon’un model katmanını tamamen bypass edip PDO ile ham SQL sorguları kullanmak. Neden? Çünkü PHQL, modeli `initialize` eder ve `SoftDelete` davranışını devre dışı bırakamazsın. İşte adım adım çözüm:

#### Adım 1: PDO ile Ham SQL

`Notes` modelinde kalıcı silme için bir `deletePermanently` metodu yazalım:

```php
public function deletePermanently()
{
    $messages = [];
    $db = $this->getDI()->getDb(); // PDO bağlantısını al

    try {
        $sql = "DELETE FROM notes WHERE id = :id";
        $stmt = $db->prepare($sql);
        $stmt->execute(['id' => $this->id]);
        error_log("Deleted {$stmt->rowCount()} rows from notes for id = {$this->id}");

        return [true, $messages];
    } catch (\PDOException $e) {
        $messages[] = "Database error: {$e->getMessage()}";
        error_log("Error in deletePermanently: {$e->getMessage()}");
        return [false, $messages];
    }
}
```

#### Adım 2: Controller’da Kullanım

`NotesController`’da bu metodu çağıran bir action yazalım:

```php
public function deletePermanentlyAction()
{
    $json = $this->request->getJsonRawBody();

    if (!isset($json->noteId)) {
        return $this->response->setJsonContent([
            'status' => 'error',
            'success' => false,
            'error' => 'Note ID is required',
            'data' => []
        ]);
    }

    $note = Notes::findFirst([
        'conditions' => '[id] = :id:',
        'bind' => ['id' => (int)$json->noteId]
    ]);

    if (!$note) {
        return $this->response->setJsonContent([
            'status' => 'error',
            'success' => false,
            'error' => 'Note not found',
            'data' => []
        ]);
    }

    try {
        [$success, $messages] = $note->deletePermanently();
        if (!$success) {
            return $this->response->setJsonContent([
                'status' => 'error',
                'success' => false,
                'error' => $messages ?: ['Failed to delete permanently'],
                'data' => []
            ]);
        }
    } catch (\Exception $e) {
        return $this->response->setJsonContent([
            'status' => 'error',
            'success' => false,
            'error' => $e->getMessage(),
            'data' => []
        ]);
    }

    return $this->response->setJsonContent([
        'status' => 'success',
        'success' => true,
        'error' => null,
        'data' => []
    ]);
}
```

#### Adım 3: Hata Ayıklama

Eğer silme işlemi başarısız olursa, veritabanı kısıtlamalarını kontrol et. Örneğin:

```php
SHOW CREATE TABLE notes_translations;
```

Foreign key varsa ve `ON DELETE CASCADE` tanımlı değilse, yukarıdaki kod zaten ilişkili kayıtları önce siliyor.

**İpucu**: Loglama ekle! Her silme işlemi sonrası etkilenen satır sayısını (`$stmt->rowCount()`) logla. Böylece hangi tablodan kaç kayıt silindiğini görebilirsin.

## Son Söz

Phalcon güçlü bir framework, ama bu tür tuzaklar her geliştiricinin başına gelebilir. `e_id` hatasını `[note_id]` ile çözmek ve `SoftDelete`’i PDO ile atlamak, saatlerce debug yapmaktan kurtarır. Umarım bu çözümler senin de projelerinde işini kolaylaştırır! Başka bir Phalcon maceranda takılırsan, bloguma göz at veya bana yaz, birlikte çözeriz!
