Αντιμετώπιση προβλημάτων

Το Nette δεν λειτουργεί, εμφανίζεται λευκή σελίδα

  • Δοκιμάστε να βάλετε το ini_set('display_errors', '1'); error_reporting(E_ALL); μετά το declare(strict_types=1); στο αρχείο index.php για να εξαναγκάσετε την εμφάνιση των σφαλμάτων.
  • Εάν εξακολουθείτε να βλέπετε μια λευκή οθόνη, πιθανόν να υπάρχει κάποιο σφάλμα στη ρύθμιση του διακομιστή και θα ανακαλύψετε τον λόγο στο αρχείο καταγραφής του διακομιστή. Για να είστε σίγουροι, ελέγξτε αν η PHP λειτουργεί καθόλου προσπαθώντας να εκτυπώσετε κάτι χρησιμοποιώντας το echo 'test';.
  • Εάν δείτε ένα σφάλμα Server Error: Λυπούμαστε! …, συνεχίστε με την επόμενη ενότητα:

Σφάλμα 500 Σφάλμα διακομιστή: Λυπούμαστε! …

Αυτή η σελίδα σφάλματος εμφανίζεται από τη Nette σε κατάσταση παραγωγής. Εάν την βλέπετε σε ένα μηχάνημα προγραμματιστή, μεταβείτε σε λειτουργία προγραμματιστή.

Εάν το μήνυμα σφάλματος περιέχει Tracy is unable to log error, μάθετε γιατί τα σφάλματα δεν μπορούν να καταγραφούν. Μπορείτε να το κάνετε αυτό, για παράδειγμα, μεταβαίνοντας σε λειτουργία προγραμματιστή και καλώντας το Tracy\Debugger::log('hello'); μετά το $configurator->enableTracy(...). Το Tracy θα σας πει γιατί δεν μπορεί να καταγραφεί. Η αιτία είναι συνήθως ανεπαρκή δικαιώματα εγγραφής στον κατάλογο log/.

Αν η πρόταση Tracy is unable to log error δεν υπάρχει στο μήνυμα σφάλματος (πλέον), μπορείτε να μάθετε την αιτία του σφάλματος στο αρχείο καταγραφής στον κατάλογο log/.

Μια από τις πιο συνηθισμένες αιτίες είναι μια ξεπερασμένη προσωρινή μνήμη. Ενώ η Nette ενημερώνει έξυπνα αυτόματα την προσωρινή μνήμη σε κατάσταση ανάπτυξης, σε κατάσταση παραγωγής εστιάζει στη μεγιστοποίηση της απόδοσης και η εκκαθάριση της προσωρινής μνήμης μετά από κάθε τροποποίηση κώδικα εξαρτάται από εσάς. Προσπαθήστε να διαγράψετε το temp/cache.

Σφάλμα #[\ReturnTypeWillChange] attribute should be used

Αυτό το σφάλμα εμφανίζεται αν έχετε αναβαθμίσει την PHP στην έκδοση 8.1 αλλά χρησιμοποιείτε τη Nette, η οποία δεν είναι συμβατή με αυτήν. Έτσι, η λύση είναι να ενημερώσετε τη Nette σε μια νεότερη έκδοση χρησιμοποιώντας το composer update. Η Nette υποστηρίζει την PHP 8.1 από την έκδοση 3.0. Αν χρησιμοποιείτε παλαιότερη έκδοση (μπορείτε να το διαπιστώσετε αναζητώντας στο composer.json), αναβαθμίστε το Nette ή μείνετε με την PHP 8.0.

Ρύθμιση δικαιωμάτων καταλόγου

Αν αναπτύσσετε σε macOS ή Linux (ή σε οποιοδήποτε άλλο σύστημα που βασίζεται σε Unix), πρέπει να ρυθμίσετε τα δικαιώματα εγγραφής στον διακομιστή ιστού. Υποθέτοντας ότι η εφαρμογή σας βρίσκεται στον προεπιλεγμένο κατάλογο /var/www/html (Fedora, CentOS, RHEL)

cd /var/www/html/MY_PROJECT
chmod -R a+rw temp log

Σε ορισμένα συστήματα Linux (Fedora, CentOS, …) το SELinux μπορεί να είναι ενεργοποιημένο από προεπιλογή. Μπορεί να χρειαστεί να ενημερώσετε τις πολιτικές SELinux ή να ορίσετε τις διαδρομές των καταλόγων temp και log με το σωστό πλαίσιο ασφαλείας SELinux. Οι κατάλογοι temp και log θα πρέπει να οριστούν στο πλαίσιο httpd_sys_rw_content_t. Για την υπόλοιπη εφαρμογή – κυρίως το φάκελο app – το πλαίσιο httpd_sys_content_t είναι αρκετό. Εκτελέστε την εφαρμογή στον διακομιστή ως διαχειριστής:

semanage fcontext -at httpd_sys_rw_content_t '/var/www/html/MY_PROJECT/log(/.*)?'
semanage fcontext -at httpd_sys_rw_content_t '/var/www/html/MY_PROJECT/temp(/.*)?'
restorecon -Rv /var/www/html/MY_PROJECT/

Στη συνέχεια, πρέπει να ενεργοποιηθεί το SELinux boolean httpd_can_network_connect_db για να επιτραπεί στη Nette να συνδεθεί στη βάση δεδομένων μέσω δικτύου. Από προεπιλογή, είναι απενεργοποιημένη. Η εντολή setsebool μπορεί να χρησιμοποιηθεί για την εκτέλεση αυτής της εργασίας, και αν καθοριστεί η επιλογή -P, αυτή η ρύθμιση θα παραμείνει σε όλες τις επανεκκινήσεις.

setsebool -P httpd_can_network_connect_db on

Πώς να αλλάξετε ή να αφαιρέσετε τον κατάλογο www από τη διεύθυνση URL;

Ο κατάλογος www/ που χρησιμοποιείται στα έργα-δείγματα στο Nette είναι ο λεγόμενος δημόσιος κατάλογος ή η ρίζα εγγράφων του έργου. Είναι ο μόνος κατάλογος του οποίου τα περιεχόμενα είναι προσβάσιμα στο πρόγραμμα περιήγησης. Και περιέχει το αρχείο index.php, το σημείο εισόδου που εκκινεί μια εφαρμογή ιστού γραμμένη σε Nette.

Για να εκτελέσετε την εφαρμογή στη φιλοξενία, πρέπει να ορίσετε το document-root σε αυτόν τον κατάλογο στη διαμόρφωση της φιλοξενίας. Ή, αν η φιλοξενία έχει έναν προκαθορισμένο φάκελο για τον δημόσιο κατάλογο με διαφορετικό όνομα (για παράδειγμα web, public_html κ.λπ.), απλά μετονομάστε τον σε www/.

Η λύση δεν είναι να “ξεφορτωθείτε” το φάκελο www/ χρησιμοποιώντας κανόνες στο αρχείο .htaccess ή στο δρομολογητή. Αν η φιλοξενία δεν σας επιτρέπει να ορίσετε το document-root σε υποκατάλογο (δηλ. να δημιουργήσετε καταλόγους ένα επίπεδο πάνω από τον δημόσιο κατάλογο), αναζητήστε άλλον. Διαφορετικά, θα αναλάβετε ένα σημαντικό ρίσκο ασφάλειας. Θα ήταν σαν να ζείτε σε ένα διαμέρισμα όπου δεν μπορείτε να κλείσετε την εξώπορτα και είναι πάντα ορθάνοιχτη.

Πώς να διαμορφώσετε έναν διακομιστή για ωραίες διευθύνσεις URL;

Apache: Η επέκταση mod_rewrite πρέπει να επιτρέπεται και να ρυθμίζεται σε ένα αρχείο .htaccess.

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]

Για να αλλάξετε τις ρυθμίσεις του Apache με αρχεία .htaccess, πρέπει να ενεργοποιήσετε την οδηγία AllowOverride. Αυτή είναι η προεπιλεγμένη συμπεριφορά για τον Apache.

nginx: η οδηγία try_files πρέπει να χρησιμοποιείται στις ρυθμίσεις του διακομιστή:

location / {
	try_files $uri $uri/ /index.php$is_args$args;  # $is_args$args is important
}

Το μπλοκ location πρέπει να ορίζεται ακριβώς μία φορά για κάθε διαδρομή συστήματος αρχείων στο μπλοκ server. Εάν έχετε ήδη ένα μπλοκ location / στη διαμόρφωσή σας, προσθέστε την οδηγία try_files στο υπάρχον μπλοκ.

Η Nette παράγει συνδέσμους με το ίδιο πρωτόκολλο που χρησιμοποιεί η τρέχουσα σελίδα. Έτσι, στη σελίδα https://foo και αντίστροφα. Αν βρίσκεστε πίσω από έναν αντίστροφο διακομιστή μεσολάβησης που απογυμνώνει το HTTPS (για παράδειγμα, στο Docker), τότε πρέπει να ρυθμίσετε έναν διακομιστή μεσολάβησης στις ρυθμίσεις για να λειτουργήσει σωστά η ανίχνευση πρωτοκόλλου.

Αν χρησιμοποιείτε το Nginx ως διακομιστή μεσολάβησης, θα πρέπει να έχετε ρυθμίσει την ανακατεύθυνση ως εξής:

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://IP-aplikace:80;  # IP or hostname of the server/container where the application is running
}

Στη συνέχεια, πρέπει να καθορίσετε το διακομιστή μεσολάβησης IP και, αν ισχύει, την περιοχή IP του τοπικού σας δικτύου όπου εκτελείτε την υποδομή:

http:
	proxy: IP-proxy/IP-range

Χρήση των χαρακτήρων { } στη JavaScript

Οι χαρακτήρες { and } χρησιμοποιούνται για τη συγγραφή ετικετών Latte. Ό,τι (εκτός από το κενό και τα εισαγωγικά) ακολουθεί το { character is considered a tag. If you need to print character { (συχνά στη JavaScript), μπορείτε να βάλετε ένα κενό (ή άλλο κενό χαρακτήρα) αμέσως μετά το {. Με αυτόν τον τρόπο αποφεύγετε την ερμηνεία του ως ετικέτα.

Αν είναι απαραίτητο να εκτυπώσετε αυτούς τους χαρακτήρες σε μια κατάσταση όπου θα ερμηνεύονταν ως ετικέτα, μπορείτε να χρησιμοποιήσετε ειδικές ετικέτες για να εκτυπώσετε αυτούς τους χαρακτήρες – {l} για { and {r} για }.

{is tag}
{ is not tag }
{l}is not tag{r}

Σημείωση Presenter::getContext() is deprecated

Το Nette είναι μακράν το πρώτο πλαίσιο PHP που πέρασε στην έγχυση εξαρτήσεων και οδήγησε τους προγραμματιστές να το χρησιμοποιούν με συνέπεια, ξεκινώντας από τους παρουσιαστές. Αν ένας παρουσιαστής χρειάζεται μια εξάρτηση, θα τη ζητήσει. Αντίθετα, ο τρόπος με τον οποίο περνάμε ολόκληρο το DI container σε μια κλάση και αυτή αντλεί τις εξαρτήσεις από αυτήν απευθείας θεωρείται αντιπρότυπο (ονομάζεται service locator). Αυτός ο τρόπος χρησιμοποιήθηκε στη Nette 0.x πριν από την έλευση του dependency injection, και κατάλοιπό του είναι η μέθοδος Presenter::getContext(), που έχει χαρακτηριστεί προ πολλού ως απαρχαιωμένη.

Αν μεταφέρετε μια πολύ παλιά εφαρμογή Nette, μπορεί να διαπιστώσετε ότι εξακολουθεί να χρησιμοποιεί αυτή τη μέθοδο. Έτσι, από την έκδοση 3.1 του nette/application θα συναντήσετε την προειδοποίηση Nette\Application\UI\Presenter::getContext() is deprecated, use dependency injection, από την έκδοση 4.0 θα συναντήσετε το σφάλμα ότι η μέθοδος δεν υπάρχει.

Η καθαρή λύση, φυσικά, είναι να επανασχεδιάσετε την εφαρμογή ώστε να περνάει εξαρτήσεις χρησιμοποιώντας dependency injection. Ως εναλλακτική λύση, μπορείτε να προσθέσετε τη δική σας μέθοδο getContext() στον βασικό σας παρουσιαστή και να παρακάμψετε το μήνυμα:

abstract BasePresenter extends Nette\Application\UI\Presenter
{
	private Nette\DI\Container $context;

	public function injectContext(Nette\DI\Container $context)
	{
		$this->context = $context;
	}

	public function getContext(): Nette\DI\Container
	{
		return $this->context;
	}
}
έκδοση: 4.0