Bootstrap
Bootstrap, ortamı başlatan, bir bağımlılık enjeksiyonu (DI) konteyneri oluşturan ve uygulamayı başlatan önyükleme kodudur. Tartışacağız:
- NEON dosyalarını kullanarak uygulamanızı nasıl yapılandırırsınız
- üretim ve geliştirme modlarının nasıl ele alınacağı
- DI konteyneri nasıl oluşturulur
İster web tabanlı ister komut satırı komut dosyaları olsun, uygulamalar bir tür ortam başlatma ile başlar. Eski
zamanlarda, bundan sorumlu olan ve başlangıç dosyasına dahil edilen eg include.inc.php
adlı bir dosya
olabilirdi. Modern Nette uygulamalarında bunun yerini, uygulamanın bir parçası olarak app/Bootstrap.php
adresinde
bulunabilen Bootstrap
sınıfı almıştır. Örneğin aşağıdaki gibi görünebilir:
use Nette\Bootstrap\Configurator;
class Bootstrap
{
private Configurator $configurator;
private string $rootDir;
public function __construct()
{
$this->rootDir = dirname(__DIR__);
// Yapılandırıcı, uygulama ortamını ve hizmetlerini ayarlamaktan sorumludur.
$this->configurator = new Configurator;
// Nette tarafından oluşturulan geçici dosyalar için dizini ayarlayın (örn. derlenmiş şablonlar)
$this->configurator->setTempDirectory($this->rootDir . '/temp');
}
public function bootWebApplication(): Nette\DI\Container
{
$this->initializeEnvironment();
$this->setupContainer();
return $this->configurator->createContainer();
}
private function initializeEnvironment(): void
{
// Nette akıllıdır ve geliştirme modu otomatik olarak açılır,
// ya da aşağıdaki satırın yorumunu kaldırarak belirli bir IP adresi için etkinleştirebilirsiniz:
// $this->configurator->setDebugMode('secret@23.75.345.200');
// Tracy'yi etkinleştirir: nihai "İsviçre çakısı" hata ayıklama aracı.
$this->configurator->enableTracy($this->rootDir . '/log');
// RobotLoader: verilen dizindeki tüm sınıfları otomatik yükler
$this->configurator->createRobotLoader()
->addDirectory(__DIR__)
->register();
}
private function setupContainer(): void
{
// Yapılandırma dosyalarını yükle
$this->configurator->addConfig($this->rootDir . '/config/common.neon');
}
}
index.php
Web uygulamaları için başlangıç dosyası index.php
, www/
genel dizininde bulunur. Ortamı
başlatmak ve bir DI konteyneri oluşturmak için Bootstrap
sınıfını kullanır. Ardından, web uygulamasını
başlatan kapsayıcıdan Application
hizmetini alır:
$bootstrap = new App\Bootstrap;
// Ortamı başlatma + bir DI konteyneri oluşturma
$container = $bootstrap->bootWebApplication();
// DI konteyneri bir Nette\Application\Application nesnesi oluşturur
$application = $container->getByType(Nette\Application\Application::class);
// Nette uygulamasını başlatın ve gelen isteği işleyin
$application->run();
Gördüğünüz gibi, şimdi daha ayrıntılı olarak tanıtacağımız Nette\Bootstrap\Configurator sınıfı, ortamın ayarlanmasına ve bir bağımlılık enjeksiyonu (DI) konteyneri oluşturulmasına yardımcı olur.
Geliştirme ve Üretim Modu
Nette, bir geliştirme veya üretim sunucusunda çalışmasına bağlı olarak farklı davranır:
- 🛠️ Geliştirme Modu
- Tracy hata ayıklama çubuğunu yararlı bilgilerle birlikte görüntüler (örn. SQL sorguları, yürütme süresi, bellek kullanımı).
- Bir hata oluştuğunda işlev çağrısı izlerini ve değişken içeriklerini içeren ayrıntılı bir hata sayfası gösterir.
- Latte şablonları, yapılandırma dosyaları vb. değiştirildiğinde önbelleği otomatik olarak yeniler.
- 🚀 Üretim Modu
- Herhangi bir hata ayıklama bilgisi göstermez; tüm hatalar günlüğe kaydedilir.
- Bir hata oluştuğunda
ErrorPresenter
veya genel bir “Sunucu Hatası” sayfası gösterir. - Önbellek asla otomatik olarak yenilenmez!
- Hız ve güvenlik için optimize edilmiştir.
Mod otomatik olarak belirlenir, bu nedenle çoğu durumda manuel olarak yapılandırmaya veya değiştirmeye gerek yoktur:
- Geliştirme modu: Bir proxy kullanılmadığı sürece (yani HTTP üstbilgilerine göre) localhost'ta (IP adresi
127.0.0.1
veya::1
) etkin. - Üretim modu: Diğer her yerde aktif.
Geliştirme modunu diğer durumlarda, örneğin belirli bir IP adresinden erişen programcılar için etkinleştirmek
istiyorsanız, setDebugMode()
adresini kullanabilirsiniz:
$this->configurator->setDebugMode('23.75.345.200'); // bir veya daha fazla IP adresi
Bir IP adresini bir çerezle birleştirmenizi kesinlikle öneririz. nette-debug
çerezine gizli bir belirteç
depolayacağız, örneğin secret1234
ve geliştirme modu, bu IP ve çerez kombinasyonuna sahip programcılar için
etkinleştirilecektir.
$this->configurator->setDebugMode('secret1234@23.75.345.200');
Ayrıca localhost için bile geliştirici modunu tamamen kapatabiliriz:
$this->configurator->setDebugMode(false);
true
değerinin, bir üretim sunucusunda asla gerçekleşmemesi gereken geliştirici modunu zorlayarak
açtığını unutmayın.
Hata Ayıklama Aracı Tracy
Kolay hata ayıklama için harika araç Tracy'yi açacağız. Geliştirici modunda hataları görselleştirir ve üretim modunda hataları belirtilen dizine kaydeder:
$this->configurator->enableTracy($this->rootDir . '/log');
Geçici Dosyalar
Nette, DI konteyneri, RobotLoader, şablonlar vb. için önbelleği kullanır. Bu nedenle, önbelleğin depolanacağı dizinin yolunu ayarlamak gerekir:
$this->configurator->setTempDirectory($this->rootDir . '/temp');
Linux veya macOS üzerinde, log/
ve temp/
dizinleri için yazma izinlerini ayarlayın.
RobotLoader
Genellikle, RobotLoader'ı kullanarak sınıfları otomatik olarak
yüklemek isteyeceğiz, bu yüzden onu başlatmalı ve Bootstrap.php
'un bulunduğu dizinden (yani
__DIR__
) ve tüm alt dizinlerinden sınıfları yüklemesine izin vermeliyiz:
$this->configurator->createRobotLoader()
->addDirectory(__DIR__)
->register();
Alternatif bir yol da sadece Composer PSR-4 otomatik yüklemeyi kullanmaktır.
Zaman Dilimi
Yapılandırıcı, uygulamanız için bir saat dilimi belirlemenize olanak tanır.
$this->configurator->setTimeZone('Europe/Prague');
DI Konteyner Yapılandırması
Önyükleme sürecinin bir parçası, tüm uygulamanın kalbi olan bir DI konteynerinin, yani nesneler için bir fabrikanın oluşturulmasıdır. Bu aslında Nette tarafından oluşturulan ve bir önbellek dizininde saklanan bir PHP sınıfıdır. Fabrika, temel uygulama nesnelerini üretir ve yapılandırma dosyaları, bunların nasıl oluşturulacağı ve yapılandırılacağı konusunda talimat verir ve böylece tüm uygulamanın davranışını etkileriz.
Konfigürasyon dosyaları genellikle NEON formatında yazılır. Nelerin yapılandırılabileceğini buradan okuy abilirsiniz.
Geliştirme modunda, kodu veya yapılandırma dosyalarını her değiştirdiğinizde kapsayıcı otomatik olarak güncellenir. Üretim modunda, yalnızca bir kez oluşturulur ve performansı en üst düzeye çıkarmak için dosya değişiklikleri kontrol edilmez.
Yapılandırma dosyaları addConfig()
kullanılarak yüklenir:
$this->configurator->addConfig($this->rootDir . '/config/common.neon');
Birden fazla dosya eklemek için addConfig()
yöntemi birden fazla kez çağrılabilir.
$configDir = $this->rootDir . '/config';
$this->configurator->addConfig($configDir . '/common.neon');
$this->configurator->addConfig($configDir . '/services.neon');
if (PHP_SAPI === 'cli') {
$this->configurator->addConfig($configDir . '/cli.php');
}
cli.php
adı bir yazım hatası değildir, yapılandırma bir dizi olarak döndüren bir PHP dosyasına da
yazılabilir.
Alternatif olarak, daha fazla yapılandırma dosyası yüklemek için includes
bölümünü
kullanabiliriz.
Aynı anahtarlara sahip öğeler yapılandırma dosyalarında görünürse, diziler söz konusu olduğunda bunların üzerine yazılır veya birleştirilir. Daha
sonra dahil edilen dosyanın bir öncekinden daha yüksek önceliği vardır. includes
bölümünün listelendiği
dosya, içine dahil edilen dosyalardan daha yüksek önceliğe sahiptir.
Statik Parametreler
Yapılandırma dosyalarında kullanılan parametreler parameters
bölümünde
tanımlanabilir ve ayrıca addStaticParameters()
yöntemi ( addParameters()
takma adı vardır)
tarafından geçirilebilir (veya üzerine yazılabilir). Farklı parametre değerlerinin ek DI konteynerlerinin, yani ek
sınıfların oluşturulmasına neden olması önemlidir.
$this->configurator->addStaticParameters([
'projectId' => 23,
]);
Yapılandırma dosyalarında, projectId
adlı parametreye erişmek için %projectId%
normal
notasyonunu yazabiliriz.
Dinamik Parametreler
Konteynere dinamik parametreler de ekleyebiliriz, statik parametrelerin aksine farklı değerleri yeni DI konteynerlerinin oluşturulmasına neden olmaz.
$this->configurator->addDynamicParameters([
'remoteIp' => $_SERVER['REMOTE_ADDR'],
]);
Ortam değişkenleri dinamik parametreler kullanılarak kolayca kullanılabilir hale getirilebilir. Bunlara yapılandırma
dosyalarındaki %env.variable%
adresinden erişebiliriz.
$this->configurator->addDynamicParameters([
'env' => getenv(),
]);
Varsayılan Parametreler
Yapılandırma dosyalarında aşağıdaki statik parametreleri kullanabilirsiniz:
%appDir%
,Bootstrap.php
dosyasının dizinine giden mutlak yoldur%wwwDir%
,index.php
giriş dosyasını içeren dizinin mutlak yoludur%tempDir%
geçici dosyalar için dizinin mutlak yoludur%vendorDir%
Composer'ın kütüphaneleri yüklediği dizinin mutlak yoludur%rootDir%
projenin kök dizinine giden mutlak yoldur%debugMode%
uygulamanın hata ayıklama modunda olup olmadığını gösterir%consoleMode%
isteğin komut satırı üzerinden gelip gelmediğini gösterir
İthal Hizmetler
Şimdi daha derine iniyoruz. Bir DI konteynerinin amacı nesneler oluşturmak olsa da, istisnai olarak mevcut bir nesneyi
konteynere ekleme ihtiyacı olabilir. Bunu, servisi imported: true
niteliği ile tanımlayarak yaparız.
services:
myservice:
type: App\Model\MyCustomService
imported: true
Yeni bir örnek oluşturun ve bootstrap'e ekleyin:
$this->configurator->addServices([
'myservice' => new App\Model\MyCustomService('foobar'),
]);
Farklı Ortamlar
Bootstrap
sınıfını ihtiyaçlarınıza göre özelleştirmekten çekinmeyin. Web projeleri arasında ayrım
yapmak için bootWebApplication()
yöntemine parametreler ekleyebilirsiniz. Alternatif olarak, birim testleri için
ortamı başlatmak üzere bootTestEnvironment()
, komut satırından çağrılan betikler için
bootConsoleApplication()
gibi başka yöntemler de ekleyebilirsiniz.
public function bootTestEnvironment(): Nette\DI\Container
{
Tester\Environment::setup(); // Nette Tester başlatma
$this->setupContainer();
return $this->configurator->createContainer();
}
public function bootConsoleApplication(): Nette\DI\Container
{
$this->configurator->setDebugMode(false);
$this->initializeEnvironment();
$this->setupContainer();
return $this->configurator->createContainer();
}