Bootstrap
Bootstrap, ortamı başlatan, bağımlılık enjeksiyonu (DI) konteynerini oluşturan ve uygulamayı başlatan bir başlatma kodudur. Şunları ele alacağız:
- NEON dosyaları kullanılarak nasıl yapılandırılır
- üretim ve geliştirme modları nasıl ayırt edilir
- DI konteyneri nasıl oluşturulur
Uygulamalar, ister web uygulamaları ister komut satırından çalıştırılan betikler olsun, çalışmalarına bir tür
ortam başlatma ile başlarlar. Eski zamanlarda, bu genellikle ilk dosyanın dahil ettiği include.inc.php
gibi bir
dosyanın sorumluluğundaydı. Modern Nette uygulamalarında, bunun yerini uygulamanın bir parçası olarak
app/Bootstrap.php
dosyasında bulunan Bootstrap
sınıfı almıştır. Örneğin şöyle
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 servisleri ayarlamaktan sorumludur.
$this->configurator = new Configurator;
// Nette tarafından oluşturulan geçici dosyalar için dizini ayarlar (ö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,
// veya 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: hata ayıklama için nihai "İsviçre çakısı".
$this->configurator->enableTracy($this->rootDir . '/log');
// RobotLoader: seçilen dizindeki tüm sınıfları otomatik olarak yükler
$this->configurator->createRobotLoader()
->addDirectory(__DIR__)
->register();
}
private function setupContainer(): void
{
// Yapılandırma dosyalarını yükler
$this->configurator->addConfig($this->rootDir . '/config/common.neon');
}
}
index.php
Web uygulamaları durumunda ilk dosya, genel dizinde www/
bulunan index.php
dosyasıdır. Bu dosya, Bootstrap sınıfından ortamı başlatmasını ve DI konteynerini
oluşturmasını ister. Ardından, web uygulamasını başlatan Application
servisini ondan alır:
$bootstrap = new App\Bootstrap;
// Ortamı başlat + DI konteynerini oluştur
$container = $bootstrap->bootWebApplication();
// DI konteyneri Nette\Application\Application nesnesini oluşturur
$application = $container->getByType(Nette\Application\Application::class);
// Nette uygulamasını başlat ve gelen isteği işle
$application->run();
Gördüğünüz gibi, ortamı ayarlamaya ve bağımlılık enjeksiyonu (DI) konteynerini oluşturmaya Nette\Bootstrap\Configurator sınıfı yardımcı olur, şimdi onu daha yakından tanıyacağız.
Geliştirme vs Üretim Modu
Nette, geliştirme veya üretim sunucusunda çalışıp çalışmadığına bağlı olarak farklı davranır:
- 🛠️ Geliştirme Modu (Development)
- Yararlı bilgilerle (SQL sorguları, yürütme süresi, kullanılan bellek) Tracy hata ayıklama çubuğunu gösterir
- Bir hata durumunda, fonksiyon çağrıları ve değişken içerikleriyle ayrıntılı bir hata sayfası gösterir
- Latte şablonları değiştiğinde, yapılandırma dosyaları düzenlendiğinde vb. önbelleği otomatik olarak yeniler
- 🚀 Üretim Modu (Production)
- Hata ayıklama bilgisi göstermez, tüm hataları günlüğe yazar
- Bir hata durumunda, ErrorPresenter'ı veya genel “Server Error” sayfasını gösterir
- Önbellek asla otomatik olarak yenilenmez!
- Hız ve güvenlik için optimize edilmiştir
Mod seçimi otomatik algılama ile yapılır, bu nedenle genellikle herhangi bir şeyi yapılandırmaya veya manuel olarak değiştirmeye gerek yoktur:
- geliştirme modu: localhost'ta (IP adresi
127.0.0.1
veya::1
) proxy mevcut değilse (yani HTTP başlığı yoksa) - üretim modu: her yerde
Geliştirme modunu diğer durumlarda da etkinleştirmek istersek, örneğin belirli bir IP adresinden erişen programcılar
için, setDebugMode()
kullanırız:
$this->configurator->setDebugMode('23.75.345.200'); // IP adresleri dizisi de belirtilebilir
Kesinlikle IP adresini bir çerezle birleştirmenizi öneririz. nette-debug
çerezine gizli bir belirteç,
örneğin secret1234
kaydederiz ve bu şekilde belirli bir IP adresinden erişen ve aynı zamanda çerezde belirtilen
belirtece sahip olan programcılar için geliştirme modunu etkinleştiririz:
$this->configurator->setDebugMode('secret1234@23.75.345.200');
Geliştirme modunu tamamen kapatabiliriz, localhost için bile:
$this->configurator->setDebugMode(false);
Dikkat, true
değeri geliştirme modunu zorla açar, bu üretim sunucusunda asla olmamalıdır.
Hata Ayıklama Aracı Tracy
Kolay hata ayıklama için harika Tracy aracını da etkinleştireceğiz. Geliştirme modunda hataları görselleştirir ve üretim modunda hataları belirtilen dizine günlüğe kaydeder:
$this->configurator->enableTracy($this->rootDir . '/log');
Geçici Dosyalar
Nette, DI konteyneri, RobotLoader, şablonlar vb. için önbellek kullanır. Bu nedenle, önbelleğin depolanacağı dizinin yolunu ayarlamak gerekir:
$this->configurator->setTempDirectory($this->rootDir . '/temp');
Linux veya macOS'ta, log/
ve temp/
dizinlerine 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
dosyasının bulunduğu dizinden (yani
__DIR__
) ve tüm alt dizinlerden sınıfları yüklemesine izin vermeliyiz:
$this->configurator->createRobotLoader()
->addDirectory(__DIR__)
->register();
Alternatif bir yaklaşım, PSR-4'e uyarak sınıfları yalnızca Composer aracılığıyla yüklemektir.
Zaman Dilimi
Yapılandırıcı aracılığıyla varsayılan zaman dilimini ayarlayabilirsiniz.
$this->configurator->setTimeZone('Europe/Prague');
DI Konteyner Yapılandırması
Başlatma sürecinin bir parçası, tüm uygulamanın kalbi olan nesneler için bir fabrika olan DI konteynerinin oluşturulmasıdır. Aslında bu, Nette tarafından oluşturulan ve önbellek dizinine kaydedilen bir PHP sınıfıdır. Fabrika, uygulamanın temel nesnelerini üretir ve yapılandırma dosyaları aracılığıyla ona nasıl oluşturulacağını ve ayarlanacağını bildiririz, böylece tüm uygulamanın davranışını etkileriz.
Yapılandırma dosyaları genellikle NEON formatında yazılır. Ayrı bir bölümde, nelerin yapılandırılabileceğini öğreneceksiniz.
Geliştirme modunda, kod veya yapılandırma dosyaları her değiştiğinde konteyner otomatik olarak güncellenir. Üretim modunda, yalnızca bir kez oluşturulur ve performansı en üst düzeye çıkarmak için değişiklikler kontrol edilmez.
Yapılandırma dosyalarını addConfig()
kullanarak yükleriz:
$this->configurator->addConfig($this->rootDir . '/config/common.neon');
Daha fazla yapılandırma dosyası eklemek istiyorsak, addConfig()
fonksiyonunu birden çok kez
çağırabiliriz.
$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ında da
yazılabilir.
Ayrıca `includes` bölümünde |dependency-injection:configuration başka yapılandırma dosyaları da ekleyebiliriz.
Yapılandırma dosyalarında aynı anahtarlara sahip öğeler görünürse, bunlar üzerine yazılır veya diziler durumunda birleştirilir. Daha sonra
eklenen dosya, öncekinden daha yüksek önceliğe sahiptir. includes
bölümünün belirtildiği dosya, içine dahil
edilen dosyalardan daha yüksek önceliğe sahiptir.
Statik Parametreler
Yapılandırma dosyalarında kullanılan parametreleri parameters
bölümünde
tanımlayabilir ve ayrıca addStaticParameters()
metoduyla (diğer adı addParameters()
) iletebilir
(veya üzerine yazabiliriz). Önemli olan, farklı parametre değerlerinin ek DI konteynerlerinin, yani ek sınıfların
oluşturulmasına neden olmasıdır.
$this->configurator->addStaticParameters([
'projectId' => 23,
]);
projectId
parametresine yapılandırmada normal %projectId%
gösterimiyle başvurulabilir.
Dinamik Parametreler
Konteynere dinamik parametreler de ekleyebiliriz; bunların farklı değerleri, statik parametrelerin aksine, yeni DI konteynerlerinin oluşturulmasına neden olmaz.
$this->configurator->addDynamicParameters([
'remoteIp' => $_SERVER['REMOTE_ADDR'],
]);
Bu şekilde, örneğin ortam değişkenlerini kolayca ekleyebiliriz, bunlara daha sonra yapılandırmada
%env.variable%
gösterimiyle başvurulabilir.
$this->configurator->addDynamicParameters([
'env' => getenv(),
]);
Varsayılan Parametreler
Yapılandırma dosyalarında şu statik parametreleri kullanabilirsiniz:
%appDir%
,Bootstrap.php
dosyasını içeren dizine mutlak yoldur%wwwDir%
, giriş dosyasıindex.php
dosyasını içeren dizine mutlak yoldur%tempDir%
, geçici dosyalar için dizine mutlak yoldur%vendorDir%
, Composer'ın kütüphaneleri kurduğu dizine mutlak yoldur%rootDir%
, projenin kök dizinine mutlak yoldur%debugMode%
, uygulamanın hata ayıklama modunda olup olmadığını belirtir%consoleMode%
, isteğin komut satırından gelip gelmediğini belirtir
İçe Aktarılan Servisler
Şimdi daha derine iniyoruz. DI konteynerinin amacı nesneleri üretmek olsa da, istisnai olarak mevcut bir nesneyi konteynere
ekleme ihtiyacı doğabilir. Bunu, servisi imported: true
bayrağıyla tanımlayarak yaparız.
services:
myservice:
type: App\Model\MyCustomService
imported: true
Ve bootstrap'ta nesneyi konteynere ekleriz:
$this->configurator->addServices([
'myservice' => new App\Model\MyCustomService('foobar'),
]);
Farklı Ortam
Bootstrap sınıfını ihtiyaçlarınıza göre değiştirmekten çekinmeyin. Web projelerini ayırt etmek için
bootWebApplication()
metoduna parametreler ekleyebilirsiniz. Veya birim testleri için ortamı başlatan
bootTestEnvironment()
, komut satırından çağrılan betikler için bootConsoleApplication()
gibi
başka metotlar ekleyebiliriz.
public function bootTestEnvironment(): Nette\DI\Container
{
Tester\Environment::setup(); // Nette Tester'ı başlat
$this->setupContainer();
return $this->configurator->createContainer();
}
public function bootConsoleApplication(): Nette\DI\Container
{
$this->configurator->setDebugMode(false);
$this->initializeEnvironment();
$this->setupContainer();
return $this->configurator->createContainer();
}