Sorun Giderme
- Nette Çalışmıyor, Beyaz Sayfa Görünüyor
- Hata 500 Server Error: We're sorry! …
- Hata 404, Yönlendirme Çalışmıyor
- Şablonlardaki ya da Yapılandırmadaki Değişiklikler Yansımıyor
- Geliştirme Sırasında Önbellek Nasıl Kapatılır?
- #[\ReturnTypeWillChange] attribute should be used Hatası
- Dizin İzinlerini Ayarlama
- URL'den www Dizini Nasıl Değiştirilir ya da Kaldırılır?
- Güzel URL'ler İçin Sunucu Nasıl Yapılandırılır?
- .htaccess Çalışıyor mu Sınayın
- mod_rewrite Etkin mi Sınayın
- Bağlantılar https: Olmadan Üretiliyor
- JavaScript'te { } Karakterlerinin Kullanımı
- Cannot modify header information - headers already sent Hatası
- Presenter::getContext() is deprecated Uyarısı
Nette Çalışmıyor, Beyaz Sayfa Görünüyor
- Hataların gösterilmesini zorlamak için
index.phpdosyasındadeclare(strict_types=1);satırından sonraini_set('display_errors', '1'); error_reporting(E_ALL);yazmayı deneyin. - Hâlâ beyaz ekran görüyorsanız, muhtemelen sunucu yapılandırmasında bir hata vardır ve nedenini sunucu günlüğünde
bulacaksınız. Emin olmak için
echo 'test';ile bir şey yazdırmayı deneyerek PHP'nin hiç çalışıp çalışmadığını denetleyin. - Server Error: We're sorry! … hatasını görüyorsanız, bir sonraki bölümle devam edin:
Hata 500 Server Error: We're sorry! …
Bu hata sayfasını Nette üretim kipinde gösterir. Onu geliştirme makinenizde görüyorsanız, geliştirici kipine geçin; Tracy ayrıntılı bir rapor gösterecek.
Hatanın nedenini her zaman log/ dizinindeki günlükte bulabilirsiniz. Ancak hata mesajında
Tracy is unable to log error ifadesi geçiyorsa, önce hataların neden günlüklenemediğini saptayın. Bunu
örneğin geçici olarak geliştirici kipine geçip Tracy'yi başladıktan
sonra bir şey günlüklemeye bırakarak yapabilirsiniz:
// Bootstrap.php
$configurator->setDebugMode('23.75.345.200'); // sizin IP adresiniz
$configurator->enableTracy($rootDir . '/log');
\Tracy\Debugger::log('hello');
Tracy size neden günlükleyemediğini söyleyecek. Nedeni, log/ dizinine yazmak için yetersiz izinler olabilir.
500 hatasının en sık nedenlerinden biri eskimiş önbellektir. Nette, geliştirme kipinde önbelleği akıllıca otomatik
güncellerken, üretim kipinde başarımı en üst düzeye çıkarmaya odaklanır ve her kod değişikliğinden sonra önbelleği
temizlemek sizin sorumluluğunuzdadır. temp/cache dizinini silmeyi deneyin.
Hata 404, Yönlendirme Çalışmıyor
Tüm sayfalar (ana sayfa dışında) 404 hatası döndürüyorsa, bu güzel URL'ler için bir sunucu yapılandırma sorununa benziyor.
Şablonlardaki ya da Yapılandırmadaki Değişiklikler Yansımıyor
“Şablonu ya da yapılandırmayı değiştirdim, ama web sitesi hâlâ eski sürümü gösteriyor.” Bu davranış, başarım nedeniyle dosya değişikliklerini denetlemeyen ve daha önce üretilmiş önbelleği koruyan üretim kipinde ortaya çıkar.
Üretim sunucusunda her değişiklikten sonra önbelleği elle temizlemekten kaçınmak için, Bootstrap.php
dosyasında kendi IP adresiniz için geliştirme kipini etkinleştirin:
$this->configurator->setDebugMode('sizin.ip.adresiniz');
Geliştirme Sırasında Önbellek Nasıl Kapatılır?
Nette akıllıdır ve onda önbelleğe almayı kapatmanıza gerek yoktur. Geliştirme sırasında, şablonda ya da DI container yapılandırmasında bir değişiklik olduğunda önbelleği otomatik günceller. Üstelik geliştirme kipi otomatik algılamayla etkinleşir, dolayısıyla genellikle hiçbir şeyi yapılandırmaya gerek kalmaz, ya da yalnızca IP adresini.
Router'ı hata ayıklarken, örneğin yönlendirmelerin saklanabildiği tarayıcı önbelleğini kapatmanızı öneririz: Geliştirici Araçları'nı açın (Ctrl+Shift+I ya da Cmd+Option+I) ve Network panelinde önbelleği kapatan kutuyu işaretleyin.
#[\ReturnTypeWillChange] attribute should be used
Hatası
Bu hata, PHP'yi 8.1 sürümüne yükselttiyseniz ama Nette'in onunla uyumlu olmayan bir sürümünü kullanıyorsanız ortaya
çıkar. Çözüm, composer update ile Nette'i daha yeni bir sürüme güncellemektir. Nette, 3.0 sürümünden
beri PHP 8.1'i destekler. Daha eski bir sürüm kullanıyorsanız (composer.json dosyanızı denetleyin), Nette'i yükseltin ya da PHP 8.0'da kalın.
Dizin İzinlerini Ayarlama
macOS ya da Linux'ta (ya da Unix tabanlı başka bir sistemde) geliştiriyorsanız, web sunucusu için yazma yetkilerini
yapılandırmanız gerekir. Uygulamanızın varsayılan /var/www/html dizininde bulunduğunu varsayarsak (Fedora,
CentOS, RHEL):
cd /var/www/html/PROJEM
chmod -R a+rw temp log
Bazı Linux sistemlerinde (Fedora, CentOS, …) SELinux varsayılan olarak etkin olabilir. SELinux ilkelerini güncellemeniz ya
da temp ve log dizinlerinin yollarını doğru SELinux güvenlik bağlamıyla ayarlamanız gerekebilir.
temp ve log dizinleri httpd_sys_rw_content_t bağlamına ayarlanmalıdır; uygulamanın
geri kalanı için, başlıca app klasörü için, httpd_sys_content_t bağlamı yeterli olacaktır.
Sunucuda root olarak çalıştırın:
semanage fcontext -at httpd_sys_rw_content_t '/var/www/html/PROJEM/log(/.*)?'
semanage fcontext -at httpd_sys_rw_content_t '/var/www/html/PROJEM/temp(/.*)?'
restorecon -Rv /var/www/html/PROJEM/
Ardından, Nette'in veritabanına ağ üzerinden bağlanmasına izin vermek için httpd_can_network_connect_db
SELinux boolean değerinin etkinleştirilmesi gerekir. Varsayılan olarak kapalıdır. Bu iş için setsebool komutu
kullanılabilir; -P seçeneği belirtilirse bu ayar yeniden başlatmalar arasında kalıcı olur:
setsebool -P httpd_can_network_connect_db on
URL'den www Dizini Nasıl Değiştirilir ya da
Kaldırılır?
Nette'in örnek projelerinde kullanılan www/ dizini, projenin genel dizinini yani document-root'unu temsil eder.
İçeriğine tarayıcıdan erişilebilen tek dizin odur. Nette web uygulamasını başlatan giriş noktası olan
index.php dosyasını içerir.
Uygulamayı bir hosting hizmetinde çalıştırmak için document-root'u doğru yapılandırmanız gerekir. İki seçeneğiniz var:
- Hosting yapılandırmasında document-root'u bu dizine ayarlayın.
- Hosting'in önceden hazırlanmış bir klasörü varsa (örneğin
public_html),www/dizinini bu adla yeniden adlandırın.
Uygulamanızı, diğer klasörlere erişimi engellemek için yalnızca .htaccess ya da router
kurallarını kullanarak güvenli kılmaya asla çalışmayın.
Hosting hizmeti document-root'u bir alt dizine ayarlamaya izin vermiyorsa (yani genel dizinin bir düzey üstünde dizin oluşturmaya), başka bir sağlayıcı arayın. Aksi hâlde ciddi bir güvenlik riskiyle karşı karşıya kalırsınız. Bu, ön kapısı kapanmayan ve hep ardına kadar açık duran bir dairede yaşamak gibi olurdu.
Güzel URL'ler İçin Sunucu Nasıl Yapılandırılır?
Apache: .htaccess dosyasında mod_rewrite kurallarını etkinleştirip yapılandırmanız gerekir:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(pdf|js|ico|gif|jpg|png|css|rar|zip|tar\.gz)$ index.php [L]
Sorunlarla karşılaşırsanız şunlardan emin olun:
.htaccessdosyası document-root dizininde bulunuyor (yaniindex.phpdosyasının yanında)- Apache
.htaccessdosyalarını işliyor - mod_rewrite etkin
Uygulamayı bir alt klasöre kuruyorsanız, RewriteBase ayarının satırını yorumdan çıkarıp doğru klasöre
ayarlamanız gerekebilir.
nginx: Yönlendirmenin, sunucu yapılandırmasındaki location / bloğunun içinde try_files
yönergesiyle yapılandırılması gerekir.
location / {
try_files $uri $uri/ /index.php$is_args$args; # $is_args$args ÖNEMLİDİR!
}
location bloğu, server bloğu içinde her dosya sistemi yolu için yalnızca bir kez görünmelidir.
Yapılandırmanızda zaten bir location / bloğu varsa, try_files yönergesini var olan bloğa
ekleyin.
.htaccess Çalışıyor mu Sınayın
Apache'nin .htaccess dosyanızı kullanıp kullanmadığını ya da yok sayıp saymadığını sınamanın en
basit yolu, onu bilerek bozmaktır. Dosyanın başına Test satırını koyun. Şimdi sayfayı tarayıcıda
yenilerseniz Internal Server Error görmelisiniz.
Bu hatayı görüyorsanız, bu aslında iyi! Bu, Apache'nin .htaccess dosyasını ayrıştırdığı ve oraya
koyduğumuz hatayla karşılaştığı anlamına gelir. Test satırını kaldırın.
Internal Server Error görmüyorsanız, Apache kurulumunuz .htaccess dosyasını yok sayıyor demektir.
Apache onu genellikle AllowOverride All yapılandırma yönergesi eksik olduğu için yok sayar.
Sunucuyu kendiniz barındırıyorsanız, düzeltmek yeterince kolaydır. httpd.conf ya da apache.conf
dosyanızı bir metin düzenleyicide açın, ilgili <Directory> bölümünü bulun ve şu yönergeyi
ekleyin/değiştirin:
<Directory "/var/www/htdocs"> # document root'unuzun yolu
AllowOverride All
...
Siteniz başka bir yerde barındırılıyorsa, .htaccess dosyasını orada etkinleştirip
etkinleştiremeyeceğinizi görmek için denetim panelinize bakın. Yapamıyorsanız, sizin için yapması amacıyla hosting
sağlayıcınızla iletişime geçin.
mod_rewrite Etkin mi Sınayın
.htaccess dosyasının çalıştığını doğruladıysanız,
mod_rewrite uzantısının etkin olduğunu da doğrulayabilirsiniz. .htaccess dosyasının başına
RewriteEngine On satırını koyun ve sayfayı tarayıcıda yenileyin. Internal Server Error
görüyorsanız, bu mod_rewrite'ın etkin olmadığı anlamına gelir. Onu etkinleştirmenin birkaç yolu vardır. Farklı
kurulumlarda bunun nasıl yapılabileceğine ilişkin çeşitli yollar için Stack Overflow'a bakın.
Bağlantılar https: Olmadan Üretiliyor
Nette, bağlantıları geçerli sayfanın kullandığı protokolle üretir. Yani https://foo sayfasında
https: ile başlayan bağlantılar üretir, tersi de geçerlidir. HTTPS'i sonlandıran bir ters vekil sunucunun
(örneğin Docker'da) arkasındaysanız, protokol algılamasının doğru çalışması için yapılandırmada bir vekil sunucu ayarlamanız gerekir.
Vekil sunucu olarak Nginx kullanıyorsanız, yönlendirmeyi örneğin şöyle ayarlamanız gerekir:
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_pass http://uygulama-IP:80; # uygulamanın çalıştığı sunucunun/konteynerin IP'si ya da hostname'i
}
Ayrıca yapılandırmada vekil sunucunun IP'sini ve isteğe bağlı olarak altyapıyı çalıştırdığınız yerel ağınızın IP aralığını belirtmeniz gerekir:
http:
proxy: vekil-IP/IP-aralığı
JavaScript'te { } Karakterlerinin Kullanımı
{ ve } karakterleri Latte etiketleri yazmak için kullanılır. { karakterinden sonra
gelen her şey (boşluk ve tırnak işareti dışında) bir etiket sayılır. { karakterini doğrudan yazdırmanız
gerekiyorsa (sıklıkla JavaScript'te), { hemen ardına bir boşluk (ya da başka bir boşluk karakteri)
koyabilirsiniz. Bu, onun etiket olarak yorumlanmasını engeller.
Bu karakterleri, metnin etiket olarak yorumlanacağı bir durumda yazdırmak gerekiyorsa, bu karakterleri çıktılamak için
özel etiketleri kullanabilirsiniz: { için {l} ve } için {r}.
{bu bir etikettir}
{ bu bir etiket değildir }
{l}bu bir etiket değildir{r}
Cannot modify header information - headers already sent
Hatası
Bu hata, uygulama bir HTTP başlığı (bir çerez, bir yönlendirme ya da oturumun başlatılması) göndermeye çalıştığında ve o anda tarayıcıya zaten bir çıktı gönderilmişse ortaya çıkar. Başlıklar her zaman yanıtın gövdesinden önce gelmelidir.
İki olası neden vardır: ya çıktı çok erken gider ya da başlık çok geç gönderilir.
Çıktı genellikle <?php öncesindeki ya da kapatan ?> sonrasındaki başıboş bir boşluk
veya boş satır yüzünden ya da düzenleyicinin dosyanın başına eklediği ve göstermediği bir BOM yüzünden çok erken
gider. Bu yüzden PHP dosyalarını asla ?> ile bitirmeyin. Hangi yerin önce yazdırdığını bulmak için Tracy\OutputDebugger kullanın.
Başlık genellikle oturumla çalışırken çok geç gönderilir. Nette, oturumdan ilk kez okuduğunuzda ya da ona
yazdığınızda oturumu otomatik başlatır; bu yalnızca şablon render edilirken olursa, çıktı çoktan yola çıkmıştır.
Bu yüzden oturumla en geç beforeRender() metodunda, bileşenlerde ayrıca handle<Signal>()
metotlarında çalışın.
Sorunu autoStart: true ayarıyla çözmeye çalışmayın.
Bu, robotlar dahil her ziyaretçi için oturumu başlatır ve diskte gereksiz yere çok sayıda dosya oluşturur. Varsayılan
smart değeri, oturumu yalnızca gerçekten gerektiğinde başlatır.
Presenter::getContext() is deprecated Uyarısı
Nette, dependency injection'a geçen ilk PHP framework'üydü ve programcıları onu tutarlı biçimde, doğrudan
presenter'lardan başlayarak kullanmaya yönlendirdi. Bir presenter'ın bir bağımlılığa gereksinimi varsa, onu ister. Tersine, DI container'ın tamamını bir
sınıfa aktarıp bağımlılıkları doğrudan oradan çekmesini sağlamak bir antipattern sayılır (service locator deseni
olarak bilinir). Bu yaklaşım, dependency injection ortaya çıkmadan önce Nette 0.x'te kullanılıyordu ve uzun süredir
deprecated olarak işaretli Presenter::getContext() metodu o dönemden kalma bir kalıntıdır.
Çok eski bir Nette uygulamasını taşıyorsanız, onun hâlâ bu metodu kullandığını görebilirsiniz.
nette/application 3.1 sürümünden beri
Nette\Application\UI\Presenter::getContext() is deprecated, use dependency injection uyarısıyla, 4.0 sürümünden
beri ise metodun var olmadığını bildiren bir hatayla karşılaşırsınız.
Temiz çözüm elbette uygulamayı, bağımlılıkları dependency injection ile aktaracak şekilde yeniden düzenlemektir.
Geçici bir çözüm olarak, mesajı atlatmak için temel presenter'ınıza kendi getContext() metodunuzu
ekleyebilirsiniz:
abstract class BasePresenter extends Nette\Application\UI\Presenter
{
private Nette\DI\Container $context;
public function injectContext(Nette\DI\Container $context): void
{
$this->context = $context;
}
public function getContext(): Nette\DI\Container
{
return $this->context;
}
}