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:

  1. ortamı başlatın
  2. fabrikayı alın
  3. 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:

  1. URL şu şekilde olacaktır https://example.com
  2. uygulamayı önyüklüyoruz, bir konteyner oluşturuyoruz ve Application::run()
  3. yönlendirici URL'yi bir çift olarak çözer Home:default
  4. bir HomePresenter nesnesi oluşturulur
  5. renderDefault() yöntemi çağrılır (eğer varsa)
  6. @layout.latte düzenine sahip bir default.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 💙

versiyon: 4.0