# Bootstrap ve Otomatik Yükleme

https://dev.wisecp.com/tr/bootstrap-ve-otomatik-yukleme

Hiç require etmediğiniz bir sınıf nasıl kullanılabilir hâle geliyor ve yanlış dizindeki bir dosya neden var olmayan bir sınıftır.

## Genel Bakış

Uygulama kodu Composer otomatik yükleyicisi kullanmaz. Başlangıç, sınıf adını bir dizine eşleyen tek bir yükleyici kaydeder; kural konuma bağlı. Bir sınıf, dosyası nerede durduğu ve adı ne olduğu için bulunur.

Doğru yerdeki yeni bir dosya kayıt istemez, aynı dosya bir dizin ötede görünmez olur. Yanlış eşleme, yazım hatası gibi görünen ama konumdan gelen bir "sınıf bulunamadı" hatası verir.

## Referans

### Ad Alanlı Sınıflar

Kök ad alanındaki bir sınıf sabit bir harita üzerinden çözülür. Önek dizini, sınıf adı dosyayı seçer. İki dosya adı denenir: yazıldığı gibi, sonra küçük harfli hâli.

| Ad alanı | Dizin |
| --- | --- |
| `WISECP\Components\{Ad}` | `coremio/components/{Ad}.php` |
| `WISECP\Operations\{Ad}` | `coremio/operations/{Ad}.php` |
| `WISECP\AdminComponents\{Ad}` | `templates/admin/components/{Ad}.php` |
| `WISECP\CronJobs\{Ad}` | `coremio/cronjobs/{Ad}.php` |
| `WISECP\Api\{Alt}\{Ad}` | `coremio/api/{Alt}/{Ad}.php` |
| `WISECP\Modules\{Tip}\{Ad}` | `coremio/modules/{Tip}/{Ad}/{Ad}.php` |

Modül dalı sabit bir liste değildir. Başlangıç, bulduğu her tip dizini için bir ad alanı kaydeder; yeni bir modül tipi, dizini var olduğu anda otomatik yüklenir. Düz eşlemenin tek istisnası API dalıdır: alt ad alanlarını alt dizinlere kadar izler.

### Başlangıç Nesnesi

Yükleyiciyi başlangıç sınıfı kaydeder, onu da kök bootstrap kurar. Sonrası, dört public metodu olan tek bir nesnedir.

```php
public static ?self $init = null;        // koşan örnek
public string $target;                   // istenen adres, normalize edilmiş
public array $route;                     // adresin parçaları
public array $routes;                    // aktif rota tablosu
public \Controllers $controller;         // kurulduktan sonra controller nesnesi
public \Router $router;                  // Router örneği
public static ?\Language $lang = null;   // Language örneği

public function __construct();                                  // otomatik yükleyici, config, oturum, hata katmanı
public function initRouter(): void;                             // rota tablosunu kurar; web'de sizin için yapılır
public function getAddress(bool $prefix = false): string;       // site adresi, istenirse dil önekli
public function run(): bool;                                    // adresi çözer ve controller'ı koşturur
```

- **run()**: İsteğin tamamı: rota tablosu, admin dizini tespiti, bakım ve erişim kapıları, controller dahil etme, giriş metodu. `index.php` bunu bir kez çağırır.
- **initRouter()**: Bağlantı üreten her şeyden önce gerekir. Yorumlayıcı kabuk olduğunda kök bootstrap bunu çağırır.
- **getAddress()**: `APP_URI`'nin arkasındaki değer. Aktif dil önekini taşıyan adres için true geçirin.

### Ad Alansız Sınıflar

Çekirdek sınıflar ve yardımcılar ad alanı taşımaz. Üç dizinde sırayla aranırlar, ilk isabet kazanır. Ad alanı olan bir modül onlara baştaki ters eğik çizgiyle erişir.

- **coremio/classes/**: Çatının kendisi: girdi filtreleme, yapılandırma, yönlendirme, view'lar, veritabanı, kancalar, hatalar, modül taban sınıfları.
- **coremio/helpers/**: Her tarafın paylaştığı iş mantığı: hizmetler, siparişler, faturalar, para, kullanıcılar, cron. Alan kuralları burada yaşar.
- **coremio/components/**: Controller'ların kurduğu, şablonların gösterdiği arayüz parçaları.

### Controller'lar ve Modeller Otomatik Yüklenmez

Küçük harfli ad alanları dizinlerini yansıtır ama yukarıdaki haritada yoktur. Controller dosyasını yönlendirme yola göre, model dosyasını controller'ın constructor'ı ada göre dahil eder. Web'de bu fark görünmez. Komut satırı script'inde model, kurulmadan önce require edilmelidir.

```php
// \WISECP\controllers\admin\{ad}  ->  coremio/controllers/admin/{ad}.php
// \WISECP\models\admin\{ad}       ->  coremio/models/admin/{ad}.php
// İkisi de otomatik yükleme haritasında yok, bu yüzden tek başına class_exists() false döner.

require_once CORE_DIR . 'models' . DS . 'website' . DS . 'products.php';

$model = new \WISECP\models\website\products();
```

### Karşılaşacağınız Sabitler

| Sabit | Değer | Bildirildiği yer |
| --- | --- | --- |
| `ROOT_DIR` | Kurulum dizini, sonunda ayraçla | `bootstrap.php` |
| `CORE_DIR` | `ROOT_DIR . "coremio" . DS` | `bootstrap.php` |
| `CLASS_DIR`, `HELPER_DIR`, `COMPONENTS_DIR`, `OPERATIONS_DIR` | `CORE_DIR` artı classes, helpers, components, operations | `bootstrap.php` |
| `MODULE_DIR`, `CONTROLLER_DIR`, `MODEL_DIR`, `LANG_DIR` | `CORE_DIR` artı modules, controllers, models, locale | `bootstrap.php` |
| `CONFIG_DIR`, `STORAGE_DIR`, `CACHE_DIR`, `LOG_DIR` | Yapılandırma; altında cache ve log taşıyan depolama | `bootstrap.php` |
| `TEMPLATE_DIR` | `ROOT_DIR . "templates" . DS` | `bootstrap.php` |
| `DS` | `DIRECTORY_SEPARATOR`. Yolları eğik çizgiyle değil bununla birleştirin | `bootstrap.php` |
| `CRON` | Yorumlayıcı komut satırıysa kendiliğinden tanımlanan `true` | `bootstrap.php` |
| `APP_URI` | Başlangıç nesnesinden alınan site adresi | `bootstrap.php` |
| `ADMINISTRATOR` | Çözülen admin dizininin **adı**; boolean değil, dize. Yalnız panel sunulurken tanımlıdır, paylaşılan kod onu `defined()` ile sınar | `coremio/init.php` |
| `DEMO_MODE`, `DEVELOPMENT`, `ERROR_DEBUG` | Hata ayıklama ayarları: demo, geliştirici, hata | `coremio/init.php` |
| `LOG_SAVE`, `LOG_SAVE_MODULE` | Log ayarları: genel ve modül başına | `coremio/init.php` |

## Örnek

Bir komut satırı script'i, bir isteğin başladığı gibi başlar.

```php
// Komut satırı başlangıçta algılanır; önceden hiçbir şey bildirmek gerekmez.
require __DIR__ . '/bootstrap.php';

// Ad alanlı: yukarıdaki harita üzerinden çözülür.
$table = new \WISECP\Components\Table("widgetList");

// Ad alansız: sınıf, yardımcı ve bileşen dizinlerinden çözülür.
$rate = Money::exChange(100, 'USD', 'EUR');

// Bir modülün içinden aynı çekirdek sınıflara baştaki ters eğik çizgiyle erişilir,
// çünkü önce modülün kendi ad alanı aranır.
$module = \Modules::getInstance('Currency', 'AcmeRates');
```

### Bir Script'i Web'e Kapatmak

Kurulum dizinindeki bir script aynı zamanda bir adrestir: dosya adını tahmin eden herkes onu tetikleyebilir. Kabuk için yazılmış bir script, uygulamayı yüklemeden önce diğer her şeyi reddeder.

```php
// Her web bağlamında 404 cevapla ve bunu uygulama yüklenmeden önce yap.
if (PHP_SAPI !== 'cli'
    || !defined('STDIN')
    || isset($_SERVER['REQUEST_METHOD'])
    || isset($_SERVER['HTTP_HOST'])
    || isset($_SERVER['REMOTE_ADDR'])
    || isset($_SERVER['SERVER_SOFTWARE'])) {
    if (!headers_sent()) {
        @http_response_code(404);
        @header('Content-Type: text/plain; charset=utf-8');
        @header('Cache-Control: no-store');
    }

    exit;
}

require __DIR__ . '/bootstrap.php';
```

Korumanın her parçası bilinçli. Yalnız yorumlayıcı moduna güvenilmez: yanlış yapılandırılmış sunucu dosyayı komut satırı ikilisiyle çalıştırabilir. Standart girdi zorunlu, web sunucusu değişkeni varsa istek reddedilir. Cevap 403 değil **404**'tür; yoklama dosyanın varlığını doğrulayamaz. Koruma require'ın üstünde durur, reddedilen istek hiçbir şey yüklemez.

Yalnız dahil edilen bir dosya farklı bir koruma ister: uygulamanın sabitleri yoksa reddeder, şablonlar kendini böyle korur. Web'den erişilebilir kalması gereken bir script ikisini de kullanamaz. Adresten çağrılan zamanlanmış giriş noktası böyledir; adreste bir sır ve karşı tarafta bir kontrol ister.

## Tuzaklar

> **Dosya adı sözleşmenin parçasıdır**
> 
> Dizin, dosya ve sınıf uyuşmalıdır; yükleyici yedek olarak küçük harfli adı da dener. Bir uyumsuzluk, büyük küçük harf ayrımı yapmayan dosya sisteminde çalışıp sunucuda düşebilir.

> **Komut satırı script'leri kök bootstrap'ı ister**
> 
> Yalnız başlatıcıyı çalıştırmak, yardımcıları eksik yarım bir uygulama verir. Başlangıcın tamamını çalıştıran kök bootstrap dosyasını require edin.

> **Komut satırı sizin için algılanır**
> 
> Kabuktan başlatmak istek-değil işaretini koyar, script hiçbir şey bildirmez. O işaretle başlangıçtaki bir hata standart hataya yazılır ve süreç sıfırdan farklı kodla çıkar. Üretilen view'da tema devreye girmez, rıza katmanı kısa devre yapar. Bu cevaplar script için doğru, sayfa için yanlıştır. İşareti kendisi bildiren eski script'ler etkilenmez.

## İlgili Makaleler

- [Mimariye Genel Bakış](https://dev.wisecp.com/tr/mimariye-genel-bakis)
- [Controller ve Yönlendirme](https://dev.wisecp.com/tr/controller-ve-yonlendirme)
- [Modül Anatomisi](https://dev.wisecp.com/tr/modul-anatomisi)
- [Geliştirme Ortamı Kurulumu](https://dev.wisecp.com/tr/gelistirme-ortami-kurulumu)
