2 commenti php

Evitare la visualizzazione degli errori quando il sito è on line e aperto all'utenza è di importanza cruciale per diverse ragioni: oltre che essere un'evenienza imbarazzante, questa crea "traumi" agli utenti e può costituire una rischio per la sicurezza.

Tuttavia, nei precedenti articoli, si è già evidenziato la distinzione fra visualizzazione e rilevazione degli errori: pur disattivando la visualizzazione degli errori quando il sito è in fase di produzione, la loro rilevazione è comunque opportuna per conoscere i problemi di cui soffre il nostro sito e apportare i necessari correttivi.

 

Sempre nei precedenti articoli, si è già parlato dell'importanza di gestire in maniera differente gli errori in fase di sviluppo e in fase di produzione (sito accessibile all'utenza) e si evidenziò come le due principali direttive in questo ambito fossero l'error_reporting e il display_errors

 

 

IMPOSTAZIONE DEGLI ERRORI NELLA FASE DI PRODUZIONE

L'impostazione potrà avvenire tramite il php.ini, file .htaccess da collocare nella document root o run-time attraverso un file php da includere in tutte le pagine web. Personalmente preferisco il secondo dei tre metodi proposti. 

La logica che si seguirà sarà la seguete:

  • disabilitare la visualizzazione di tutti gli errori;
  • rilevare tutti gli errori di tipo PARSE ERROR, FATAL ERROR, WARNING e NOTICE (verranno trascurati gli errori di tipo DEPRECATED e STRICT);
  • ignorare errori duplicati;
  • salvare gli errori su un file di log e impedirne l'accesso diretto (evitare che tutti possano leggerlo).

 

Settaggio tramite php.ini:

error_reporting = E_ALL & ~E_DEPRECATED
display_errors = Off
display_startup_errors = Off
log_errors = On
log_errors_max_len = 0
ignore_repeated_errors = On
ignore_repeated_source = On
track_errors = On
error_log = "/percorso/file/php_error.log"

 

Settaggio tramite .htaccess da posizionare nella root del sito:

php_value error_reporting 22527
php_flag display_errors false
php_flag display_startup_errors false
php_flag log_errors true
php_value log_errors_max_len 0
php_flag ignore_repeated_errors true
php_flag ignore_repeated_source true
php_flag report_memleaks true
php_flag track_errors true
php_value error_log /percorso/file/php_error.log

 

Ricordo che il valore numerico dell'error_reporting si è modificato nel tempo: infatti il valore della costante E_ALL nella versione di php 5.3 è di 30719, nella versione 5.2 è di 6143, mentre nelle precedenti è di 2047. Inoltre, la costante E_DEPRECATED è stata introdotta dalla versione di php superiore alla 5.3. Per ottenere il valore numerico dell'error_reporting potrete eseguite questa operazione:

<?php
echo E_ALL - (defined('E_DEPRECATED')? E_DEPRECATED : 0);
?>

 

Settaggio "run-time" all'interno di un file php:

<?php
error_reporting(E_ALL & ~E_DEPRECATED);
ini_set('display_errors',0);
ini_set('display_startup_errors',0);
ini_set('log_errors',1);
ini_set('log_errors_max_len',0);
ini_set('ignore_repeated_errors',1);
ini_set('ignore_repeated_source',1);
ini_set('report_memleaks',1);
ini_set('track_errors',1);
ini_set('error_log','/percorso/file/php_error.log');
?>

 

A questo punto dovremo impedire l'accesso al file di log attraverso direttiva da apporre nel file .htaccess:

<Files /percorso/file/php_error.log>
Order allow,deny
Deny from all
Satisfy All
</Files>

 

 

ANALISI DEGLI ERRORI RILEVATI E SALVATI SUL FILE DI LOG

Una volta fatti i seguenti settaggi sarà nostra premura analizzare periodicamente gli errori che si andranno a salvare sul file di log: ciò potrà essere fatto manualmente (accedendo al file tramite ftp) oppure tramite script php.

 

In questo secondo caso possiamo operare in diversi modi: impostare un cron job o operazione pianificata che ci invii periodicamente tramite email gli errori registrati sul file di log, oppure che ci visualizzi una notifica nel pannello di amministrazione del nostro sito.

La sua realizzazione potrà essere più o meno complessa. In ogni caso, siccome gli errori verranno scritti uno per ogni rigo questi potranno essere agevolmente letti attraverso la funzione file() di php.

<?php
// ovviamente il seguente file dovrà essere protetto...
$array_log = file('/percorso/file/php_error.log');
foreach($array_log as $error)
	{
	echo '<p>'.$error.'</p>';
	}
?>

 

Un metodo alternativo a quello appena descritto che ci consente di tener traccia in tempo reale degli errori generati dal nostro sito consiste nell'utilizzo della funzione set_error_handler() la cui trattazione sarà fatta nella prossima lezione.

Olimpio Romanella

Sono un appassionato di Web Developing con un particolare debole per php. Mi dedico principalmente dello sviluppo back-end ed in particolare programmazione lato server con php, sviluppo di database relazionali MySql e progettazione di CMS di piccole e medie dimensioni.

Mi avvalgo del framework javascript Jquery, utilizzando molti dei suoi plugin e nei dei miei progetti utilizzo spesso il framework MVC Codeigniter.

2 Commenti presenti

avatar perseo

perseo

19 February 2016 ore 12:33

Ciao Olimpio,
sto utilizzando ini_set ed error_log su server locale, per crearmi uno storico delle operazioni sul mio DB.

Anziché ripetere ogni volta lo script ad inizio di ogni pagina .php ho pensato di includere lo script da un file esterno.
Il problema è che il settaggio non ha esito, ed il file di .log viene creato nel nativo error_log di Apache.. e non nel mio_file_di_log.
Invece se il codice lo copio ad inizio di ogni pagina .php funziona tutto!

Perché con include ed include_once non ottengo lo stesso risultato?

Grazie!

avatar matt

matt

06 October 2013 ore 11:32

Ciao,
Vorrei innanzitutto farti i complementi per questa ottima ed esaustiva guida, ma segnalrti alcune gravi imprecisioni: prima di tutto, con l'ultima versione di PHP la 5.4, ma già dalla 5.3, se uso (in produzione o sviluppo) la costante E_ALL con la funzione error_reporting(), ovvero error_reporting(E_ALL); ecco che includo così anche gli errori di tipo Notice. Ecco il link al manuale ufficiale:

Costanti errore

Inoltre la stessa cosa si può ottenere con error_reporting(-1); come suggerisce il manuale qui:
Funzione error reporting

Poi se si usa un file .htaccess per cambiare le impostazioni di default del php.ini, analogamente il nuovo valore da settare per riportare TUTTI gli errori è:

php_value error_reporting 32767

ma, come indica sempre il manuale conviene usare (come del resto fai anche tu) sempre un bit value superiore, essendo sempre in evoluzione tali valori, vale a dire questo:

php_value error_reporting 2147483647

Configurazione error func

Infine la caosa più importante che dovresti indicare; su molti shared web server (server che danno hosting gratuiti) che forniscono spazio web gratis, purtoppo NON si possono settare alcune direttive qui indicate, come invece sarebbe giusto fare in produzione.

Ad esempio su altervista.org NON si possono settare NESSUNA delle seguenti direttive:

display_errors
diplay_startup_errors
log_errors
log_errors_max_len
ignore_repeated_errors
ignore_repeated_source
report_memleaks
track_errors
error_log

Lo dico, perché io due siti sui loro server ed ho provato ad usare lì questo mio script Seguendo il tuo tutoraiol), che includevo in tutte le mie pagine web, ma non funziona nulla (ho inserito per me stesso i commenti in inglese - visto che poi vado a ristudiarmi o modificare i miei script).

<?php
/*

This is for PRODUCTION.

I report all PHP errors (see changelog) but show nothing on the screen: I use the error_log2 file instead.

The default value set in php.ini, on a common shared web server which hosts sites for free like altervista.org, is E_ALL & ~E_NOTICE or E_ALL ^ E_NOTICE, which is exactly the same.
This setting does not show E_NOTICE level errors.

To see the default setting just do this:

<?php
phpinfo();
?>

You may want to show them during development.

ATTENTION: on some shared web server like altervista.org, you can only set the error_reporting directive, with the function error_reporting(), that's, you can set for instance:

error_reporting(E_ALL);
error_reporting(E_ALL ^ E_NOTICE); // the default value
error_reporting(0); // Not reporting anything at all, etc.

But you're not allowed to set the directive display_errors, as you can see here down, to switch off all errors and also to log them on a simple file instead, as it should be done in a PRODUCTION environment.

*/
error_reporting(E_ALL);
ini_set('display_errors', 'off'); // In earlier versions, this directive was of type boolean, now is string
ini_set('display_startup_errors', 0);
ini_set('log_errors', 1);
ini_set('log_errors_max_len', 0);
ini_set('ignore_repeated_errors', 1);
ini_set('ignore_repeated_source', 1);
ini_set('report_memleaks', 1);
ini_set('track_errors', 1);
ini_set('error_log', './error_log2');
?>


Come vedi dai miei commenti, altervista.org mi lascia, al massimo, spegnere il report di TUTTI gli errori, ma non mi da neanche la possibilità di crearmi un file di log....Mahh, va beh che è gratis, però...

Ovvero al massimo posso scrivere: error_reporting(0);

anche se così facendo, non avendo un file di log, non serve davvero a nulla questa possibiltà!.

Giusto per finire ho provato anche ad inserire nel file .htaccess tali istruzioni, ma non si ottiene un bel nulla neanche così.


php_value error_reporting 2147483647
php_flag display_errors true
php_flag display_startup_errors true
php_flag log_errors true
php_value log_errors_max_len 0
php_flag ignore_repeated_errors true
php_flag ignore_repeated_source true
php_flag report_memleaks true
php_flag track_errors true
php_value error_log ./error_log2

Dopo un sacco di ricerche ho trovato infatti questo wiki di altervista che conferma quanto sopra:

Configurazione .htaccess altervista

Scusami del post così lungo, ma ritenevo che dare queste info fosse basilare per molti utenti, che hanno uno o più siti su server gratuiti come altervista.org.

Ciao.