Uygulamalar Nasıl Çalışır?
Şu anda Nette dokümantasyonunun temel belgesini okumaktasınız. Web uygulamalarının tüm prensiplerini öğreneceksiniz. A'dan Z'ye, doğum anından PHP betiğinin son nefesine kadar güzel. Okuduktan sonra bileceksiniz:
- her şey nasil i̇şli̇yor
- Bootstrap, Presenter ve DI konteyner nedir
- dizin yapısının neye benzediği
Dizin Yapısı
WebProject adlı bir web uygulamasının iskelet örneğini açın ve hakkında yazılan dosyaları izleyebilirsiniz.
Dizin yapısı şuna benzer:
web-project/ ├── app/ ← directory with application │ ├── Core/ ← temel gerekli sınıflar │ │ └── RouterFactory.php ← URL adreslerinin yapılandırılması │ ├── UI/ ← presenters, templates & co. │ │ ├── @layout.latte ← paylaşılan düzen şablonu │ │ └── Home/ ← Ana Sayfa sunucu dizini │ │ ├── HomePresenter.php ← Ev sunucusu sınıfı │ │ └── default.latte ← eylem için şablon default │ └── Bootstrap.php ← booting class Bootstrap ├── bin/ ← scripts for the command line ├── config/ ← configuration files │ ├── common.neon │ └── services.neon ├── log/ ← error logs ├── temp/ ← temporary files, cache, … ├── vendor/ ← libraries installed by Composer │ ├── ... │ └── autoload.php ← autoloading of libs installed by Composer ├── www/ ← public directory, document root of project │ ├── .htaccess ← mod_rewrite rules etc │ └── index.php ← initial file that launches the application └── .htaccess ← prohibits access to all directories except www
Dizin yapısını herhangi bir şekilde değiştirebilir, klasörleri yeniden adlandırabilir veya taşıyabilir ve ardından
Bootstrap.php
dosyasındaki log/
ve temp/
yollarını ve autoload
bölümündeki composer.json
içindeki bu dosyanın yolunu düzenleyebilirsiniz. Başka bir şey yok, karmaşık
yeniden yapılandırma yok, sürekli değişiklik yok. Nette akıllı bir otomatik algılamaya sahiptir.
Biraz daha büyük uygulamalar için, sunum ve şablon içeren klasörleri alt dizinlere (diskte) ve modül olarak adlandırdığımız ad alanlarına (kodda) bölebiliriz.
www/
dizini, projenin genel dizini veya belge köküdür. Uygulama tarafında başka bir şey ayarlamanıza gerek
kalmadan yeniden adlandırabilirsiniz. Sadece barındırmayı, belge
kökünün bu dizine gideceği şekilde yapılandırmanız
gerekir.
Composer'ı kullanarak Nette dahil olmak üzere WebProject'i doğrudan da indirebilirsiniz:
composer create-project nette/web-project
Linux veya macOS üzerinde, log/
ve temp/
dizinleri için yazma izinlerini ayarlayın.
WebProject uygulaması çalışmaya hazırdır, başka bir şey yapılandırmaya gerek yoktur ve www/
klasörüne
erişerek doğrudan tarayıcıda görüntüleyebilirsiniz.
HTTP İsteği
Her şey bir kullanıcının sayfayı tarayıcıda açması ve tarayıcının sunucuya bir HTTP isteği göndermesiyle başlar.
İstek, index.php
olan www/
genel dizininde bulunan bir PHP dosyasına gider. Bunun
https://example.com/product/123
dosyasına eşlenir ve çalıştırılır.
Görevi:
- ortamı başlatın
- fabrikayı alın
- talebi işleyen Nette uygulamasını başlatın
Ne tür bir fabrika? Traktör değil, web sitesi üretiyoruz! Bekleyin, hemen açıklayacağım.
“Ortamı başlatmak” derken, örneğin, hataları günlüğe kaydetmek veya görselleştirmek için harika bir araç olan Tracy 'nin etkinleştirilmesini kastediyoruz. Üretim sunucusundaki hataları günlüğe kaydeder ve bunları doğrudan geliştirme sunucusunda görüntüler. Bu nedenle, başlatmanın sitenin üretim modunda mı yoksa geliştirici modunda mı çalıştığına da karar vermesi gerekir. Bunu yapmak için Nette otomatik algılama kullanır: siteyi localhost üzerinde çalıştırırsanız, geliştirici modunda çalışır. Hiçbir şey yapılandırmanız gerekmez ve uygulama hem geliştirme hem de üretim dağıtımı için hazırdır. Bu adımlar Bootstrap sınıfı ile ilgili bölümde ayrıntılı olarak açıklanmıştır.
Üçüncü nokta (evet, ikinciyi atladık, ancak ona geri döneceğiz) uygulamayı başlatmaktır. Nette HTTP isteklerinin
işlenmesi Nette\Application\Application
sınıfı (bundan sonra Application
olarak anılacaktır)
tarafından yapılır, bu nedenle “bir uygulamayı çalıştır” dediğimizde, bu sınıfın bir nesnesi üzerinde
run()
adlı bir yöntemi çağırmayı kastediyoruz.
Nette, kanıtlanmış metodolojilerle temiz uygulamalar yazmanız için size rehberlik eden bir akıl hocasıdır. Ve en
kanıtlanmış olanı bağımlılık enjeksiyonu, kısaltılmış DI olarak adlandırılır. Şu anda sizi DI'yi
açıklamakla meşgul etmek istemiyoruz, çünkü ayrı bir
bölüm var, burada önemli olan şey, anahtar nesnelerin genellikle DI container (kısaltılmış DIC) adı verilen
nesneler için bir fabrika tarafından oluşturulacağıdır. Evet, bu bir süre önce bahsedilen fabrikadır. Ayrıca bizim için
Application
nesnesini de oluşturur, bu yüzden önce bir konteynere ihtiyacımız var. Bunu
Configurator
sınıfını kullanarak elde ediyoruz ve Application
nesnesini üretmesine izin veriyoruz,
run()
yöntemini çağırıyoruz ve bu Nette uygulamasını başlatıyor. Bu tam olarak index.php dosyasında olan şeydir.
Nette Uygulama
Application sınıfının tek bir görevi vardır: HTTP isteğine yanıt vermek.
Nette'de yazılan uygulamalar, belirli bir web sitesi sayfasını temsil eden sınıflar olan birçok sözde sunucuya (diğer çerçevelerde aynı olan denetleyici terimiyle karşılaşabilirsiniz) ayrılır: örneğin ana sayfa; e-mağazadaki ürün; oturum açma formu; site haritası beslemesi vb. Uygulama bir ila binlerce sunucuya sahip olabilir.
Uygulama, yönlendirici olarak adlandırılan kişiden mevcut talebin işlenmek üzere hangi sunuculara iletileceğine karar
vermesini isteyerek başlar. Yönlendirici bunun kimin sorumluluğunda olduğuna karar verir.
https://example.com/product/123
ile bir ürünü id: 123
eylem olarak isteyen sunucu
Product
için bir iş olduğuna karar verir. Sunucu + eylem çiftlerini iki nokta üst üste ile ayırarak
Product:show
şeklinde yazmak iyi bir alışkanlıktır.
Böylece yönlendirici URL'yi bir Presenter:action
+ parametreler çiftine dönüştürdü, bizim durumumuzda
Product:show
+ id: 123
. Bir yönlendiricinin nasıl göründüğünü
app/Core/RouterFactory.php
dosyasında görebilirsiniz ve bunu Yönlendirme bölümünde ayrıntılı olarak açıklayacağız.
Devam edelim. Uygulama zaten sunucunun adını biliyor ve devam edebilir. Sunum yapan kişinin kodu olan
ProductPresenter
nesnesini oluşturarak Product
. Daha doğrusu, DI konteynerinden sunucuyu yaratmasını
ister, çünkü nesneleri üretmek onun işidir.
Sunucu şöyle görünebilir:
class ProductPresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private ProductRepository $repository,
) {
}
public function renderShow(int $id): void
{
// modelden veri alıyoruz ve bunu şablona aktarıyoruz
$this->template->product = $this->repository->getProduct($id);
}
}
Talep, sunum yapan kişi tarafından ele alınır. Ve görev açıktır: id: 123
ile show
eylemini
gerçekleştirin. Sunucuların dilinde bu, renderShow()
yönteminin çağrıldığı ve $id
parametresinde 123
aldığı anlamına gelir.
Bir sunum yapan kişi birden fazla eylemi işleyebilir, yani birden fazla yönteme sahip olabilir
render<Action>()
. Ancak sunum yapanların bir veya mümkün olduğunca az eylemle tasarlanmasını
öneriyoruz.
Böylece, kodu kurgusal bir örnek olan renderShow(123)
yöntemi çağrıldı, ancak verilerin şablona nasıl
aktarıldığını, yani $this->template
adresine yazarak görebilirsiniz.
Daha sonra, sunum yapan kişi yanıtı döndürür. Bu bir HTML sayfası, bir resim, bir XML belgesi, diskten bir dosya
gönderme, JSON veya başka bir sayfaya yönlendirme olabilir. Daha da önemlisi, nasıl yanıt verileceğini açıkça
belirtmezsek ( ProductPresenter
adresinde olduğu gibi), yanıt şablonu bir HTML sayfası ile işlemek olacaktır.
Neden mi? Çünkü vakaların %99'unda bir şablon çizmek isteriz, dolayısıyla sunum yapan kişi bu davranışı varsayılan
olarak kabul eder ve işimizi kolaylaştırmak ister. Nette'in amacı da bu.
Hangi şablonun işleneceğini belirtmemize bile gerek yoktur; framework yolu kendisi çıkaracaktır. show
eylemi
söz konusu olduğunda, basitçe ProductPresenter
sınıfının bulunduğu dizindeki show.latte
şablonunu yüklemeye çalışır. Ayrıca @layout.latte
dosyasındaki düzeni bulmaya çalışır ( şablon arama hakkında daha fazla bilgi).
Daha sonra şablonlar işlenir. Bu, sunucunun ve tüm uygulamanın görevini tamamlar ve iş biter. Eğer şablon mevcut değilse, 404 hata sayfası döndürülür. Sunucular hakkında daha fazla bilgi için Sunucular sayfasına bakabilirsiniz.
Sadece emin olmak için, tüm süreci biraz farklı bir URL ile özetlemeye çalışalım:
- URL şu şekilde olacaktır
https://example.com
- uygulamayı önyüklüyoruz, bir konteyner oluşturuyoruz ve
Application::run()
- yönlendirici URL'yi bir çift olarak çözer
Home:default
- bir
HomePresenter
nesnesi oluşturulur renderDefault()
yöntemi çağrılır (eğer varsa)@layout.latte
düzenine sahip birdefault.latte
şablonu oluşturulur
Şu anda birçok yeni kavramla karşılaşmış olabilirsiniz, ancak bunların anlamlı olduğuna inanıyoruz. Nette'de uygulama oluşturmak çocuk oyuncağı.
Şablonlar
Şablonlar söz konusu olduğunda, Nette Latte şablon sistemini kullanır. Bu
yüzden şablon içeren dosyalar .latte
ile biter. Latte, PHP için en güvenli şablon sistemi ve aynı zamanda en
sezgisel sistem olduğu için kullanılır. Yeni bir şey öğrenmenize gerek yok, sadece PHP ve birkaç Latte etiketi bilmeniz
yeterli. Her şeyi dokümantasyonda bulacaksınız.
Şablonda diğer sunumculara ve eylemlere aşağıdaki gibi bir bağlantı oluşturuyoruz:
<a n:href="Product:show $productId">product detail</a>
Gerçek URL yerine tanıdık Presenter:action
çiftini yazmanız ve parametreleri eklemeniz yeterlidir. İşin
püf noktası, bu özelliğin Nette tarafından işleneceğini söyleyen n:href
adresidir. Ve oluşturacaktır:
<a href="/product/456">product detail</a>
Daha önce bahsedilen yönlendirici URL'nin oluşturulmasından sorumludur. Aslında, Nette'deki yönlendiriciler, yalnızca bir URL'den bir sunumcu:eylem çiftine dönüşüm gerçekleştirebilmeleri açısından değil, aynı zamanda sunumcu + eylem + parametrelerin adından bir URL oluşturabilmeleri açısından da benzersizdir. Bu sayede Nette'de, şablonda veya sunum yapan kişide tek bir karakteri bile değiştirmeden, sadece yönlendiriciyi değiştirerek tüm bitmiş uygulamadaki URL'nin şeklini tamamen değiştirebilirsiniz. Ve bu sayede, Nette'nin bir başka benzersiz özelliği olan ve farklı URL'lerde yinelenen içeriğin varlığını otomatik olarak önleyerek SEO'yu (internette aranabilirliğin optimizasyonu) geliştiren sözde kanonizasyon çalışır. Birçok programcı bunu şaşırtıcı buluyor.
İnteraktif Bileşenler
Sunucular hakkında size söylememiz gereken bir şey daha var: yerleşik bir bileşen sistemine sahipler. Daha yaşlılarınız Delphi veya ASP.NET Web Forms'dan benzer bir şeyi hatırlayabilir. React veya Vue.js uzaktan benzer bir şey üzerine inşa edilmiştir. PHP çerçeveleri dünyasında bu tamamen benzersiz bir özelliktir.
Bileşenler, sayfalara (yani sunumlara) yerleştirdiğimiz ayrı yeniden kullanılabilir birimlerdir. Bunlar formlar, datagridler, menüler, anketler, aslında tekrar tekrar kullanılması mantıklı olan her şey olabilir. Kendi bileşenlerimizi oluşturabilir veya çok çeşitli açık kaynak bileşenlerinden bazılarını kullanabiliriz.
Bileşenler, uygulama geliştirme yaklaşımını temelden değiştirmektedir. Önceden tanımlanmış birimlerden sayfalar oluşturmak için yeni olanaklar sunacaklar. Ve Hollywood ile ortak bir yönleri var.
DI Konteyneri ve Yapılandırması
DI konteyneri (nesneler için fabrika) tüm uygulamanın kalbidir.
Merak etmeyin, önceki kelimelerden anlaşılabileceği gibi sihirli bir kara kutu değil. Aslında, Nette tarafından
oluşturulan ve bir önbellek dizininde saklanan oldukça sıkıcı bir PHP sınıfıdır. createServiceAbcd()
şeklinde adlandırılan ve her biri bir nesne yaratan ve döndüren çok sayıda metodu vardır. Evet, uygulamayı
çalıştırmak için index.php
dosyasında ihtiyaç duyduğumuz Nette\Application\Application
nesnesini
üretecek bir createServiceApplication()
yöntemi de var. Ve tek tek sunum yapan kişileri üretmek için yöntemler
var. Ve böyle devam eder.
DI konteynerinin oluşturduğu nesneler bir nedenden dolayı servis olarak adlandırılır.
Bu sınıfla ilgili gerçekten özel olan şey, sizin tarafınızdan değil, çerçeve tarafından programlanmış olmasıdır.
Aslında PHP kodunu üretir ve diske kaydeder. Siz sadece konteynerin hangi nesneleri tam olarak nasıl üretmesi gerektiğine
dair talimatlar verirsiniz. Ve bu talimatlar NEON formatındaki yapılandırma dosyalarına yazılır ve
bu nedenle .neon
uzantısına sahiptir.
Yapılandırma dosyaları yalnızca DI konteynerine talimat vermek için kullanılır. Örneğin, oturum bölümünde expiration: 14 days
seçeneğini belirtirsem, DI konteyneri oturumu temsil eden Nette\Http\Session
nesnesini oluştururken
setExpiration('14 days')
yöntemini çağırır ve böylece yapılandırma gerçek olur.
Nelerin yapılandırılabileceğini ve kendi servislerinizi nasıl tanımlayacağınızı anlatan koca bir bölüm sizin için hazır.
Hizmetlerin oluşturulmasına girdiğinizde, otomatik kab lolama kelimesiyle karşılaşacaksınız. Bu, hayatınızı inanılmaz derecede kolaylaştıracak bir araçtır. Hiçbir şey yapmanıza gerek kalmadan nesneleri ihtiyaç duyduğunuz yerlere (örneğin sınıflarınızın kurucularına) otomatik olarak aktarabilir. Nette'deki DI konteynerinin küçük bir mucize olduğunu göreceksiniz.
Sırada Ne Var?
Nette uygulamaların temel prensiplerini gözden geçirdik. Şimdiye kadar çok yüzeysel olarak, ancak yakında derinliklere inecek ve sonunda harika web uygulamaları oluşturacaksınız. Nereden devam edelim? İlk Uygulamanızı Oluşturun eğitimini denediniz mi?
Yukarıdakilere ek olarak, Nette yararlı sınıflardan, veritabanı katmanından vb. oluşan bir cephaneliğe sahiptir. Kasıtlı olarak sadece belgelere tıklamayı deneyin. Veya blogu ziyaret edin. Birçok ilginç şey keşfedeceksiniz.
Çerçeve size bolca neşe getirsin 💙