Bootstrap ve Otomatik Yükleme

1.8k görüntülenme Markdown

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.

coremio/init.php, bootstrap.php tarafından sürülür
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.

bir script'ten modele ulaşmak
// \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

SabitDeğerBildirildiği yer
ROOT_DIRKurulum dizini, sonunda ayraçlabootstrap.php
CORE_DIRROOT_DIR . "coremio" . DSbootstrap.php
CLASS_DIR, HELPER_DIR, COMPONENTS_DIR, OPERATIONS_DIRCORE_DIR artı classes, helpers, components, operationsbootstrap.php
MODULE_DIR, CONTROLLER_DIR, MODEL_DIR, LANG_DIRCORE_DIR artı modules, controllers, models, localebootstrap.php
CONFIG_DIR, STORAGE_DIR, CACHE_DIR, LOG_DIRYapılandırma; altında cache ve log taşıyan depolamabootstrap.php
TEMPLATE_DIRROOT_DIR . "templates" . DSbootstrap.php
DSDIRECTORY_SEPARATOR. Yolları eğik çizgiyle değil bununla birleştirinbootstrap.php
CRONYorumlayıcı komut satırıysa kendiliğinden tanımlanan truebootstrap.php
APP_URIBaşlangıç nesnesinden alınan site adresibootstrap.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ınarcoremio/init.php
DEMO_MODE, DEVELOPMENT, ERROR_DEBUGHata ayıklama ayarları: demo, geliştirici, hatacoremio/init.php
LOG_SAVE, LOG_SAVE_MODULELog ayarları: genel ve modül başınacoremio/init.php

Örnek

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

uygulamayı başlatan bir script
// 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.

bir komut satırı script'inin ilk satırları
// 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.

Faydalı oldu mu?

Geri bildiriminiz için teşekkürler!

Hâlâ Yardıma mı İhtiyacınız Var?

Yukarıda bulamadığınız her şey için destek ekibimiz her zaman yanınızda.