<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>lezione Archivi - Cesare Bordi | Innovation Manager &amp; Back-end Developer</title>
	<atom:link href="https://cesarebordi.it/tag/lezione/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.cesarebordi.it/tag/lezione/</link>
	<description>Innovare con soluzioni software efficaci e gioco di squadra</description>
	<lastBuildDate>Fri, 04 Sep 2020 07:27:56 +0000</lastBuildDate>
	<language>it-IT</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://cesarebordi.it/wp-content/uploads/2016/02/CB-logo-88x88.png</url>
	<title>lezione Archivi - Cesare Bordi | Innovation Manager &amp; Back-end Developer</title>
	<link>https://www.cesarebordi.it/tag/lezione/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>PSR-3 Logger Interface: standard log per PHP</title>
		<link>https://cesarebordi.it/psr-3-logger-interface-standard-log-php/</link>
					<comments>https://cesarebordi.it/psr-3-logger-interface-standard-log-php/#comments</comments>
		
		<dc:creator><![CDATA[cesarebordi]]></dc:creator>
		<pubDate>Wed, 17 Jun 2020 15:21:23 +0000</pubDate>
				<category><![CDATA[Articoli]]></category>
		<category><![CDATA[Lezioni]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[best practice]]></category>
		<category><![CDATA[guida]]></category>
		<category><![CDATA[lezione]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[logger]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[programmazione ad oggetti]]></category>
		<category><![CDATA[psr]]></category>
		<category><![CDATA[psr-3]]></category>
		<category><![CDATA[psr3]]></category>
		<category><![CDATA[standard]]></category>
		<guid isPermaLink="false">https://www.cesarebordi.it/?p=1154</guid>

					<description><![CDATA[<p>Il PSR-3 Logger Interface del PHP-FIG si propone come uno standard comune per il log degli applicativi in PHP.</p>
<p>L'articolo <a href="https://cesarebordi.it/psr-3-logger-interface-standard-log-php/">PSR-3 Logger Interface: standard log per PHP</a> sembra essere il primo su <a href="https://cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><strong>PSR-3 Logger Interface</strong> del <strong>PHP-FIG</strong> (PHP Framework Interop Group) si propone come uno standard comune per il log degli applicativi in PHP.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>The main goal is to allow libraries to receive a <em>Psr\Log\LoggerInterface </em>object and write logs to it in a simple and universal way.</p></blockquote>



<p class="wp-block-paragraph">L&#8217;obiettivo è quello di far sì che le varie componenti software possano utilizzare un oggetto di tipo <strong><em>Psr\Log\LoggerInterface</em></strong> per scrivere messaggi di log in modo semplice ed universale.</p>



<p class="wp-block-paragraph">Anche gli applicativi più complessi come i framework <strong>POTREBBERO</strong> <strong>estendere l&#8217;interfaccia del logger per arricchirla</strong> di funzioni, ma <strong>DOVREBBERO</strong> assicurarsi di mantenerne la compatibilità. In questo modo tutti i componenti e le librerie utilizzate potrebbero <strong>scrivere nei log</strong> centralizzati dell&#8217;applicativo. </p>



<p class="wp-block-paragraph">La parola <strong>implementatore</strong> (<code class="" data-line="">&lt;strong&gt;implementor&lt;/strong&gt;</code>) utilizzata nel testo dello <strong>standard PSR3</strong> rappresenta qualcuno che implementa la <code class="" data-line="">&lt;strong&gt;&lt;em&gt;LoggerInterface&lt;/em&gt;&lt;/strong&gt;</code> per inserire un logger in una libreria o framework . <br />Gli utenti dei logger vengono definiti utenti (<code class="" data-line="">user)</code>.</p>



<p class="wp-block-paragraph">Per il significato delle altre parole chiave si rimanda alle <a href="https://www.cesarebordi.it/psr-1-regole-scrittura-codice-php/#note" target="_blank" rel="noreferrer noopener">note dell&#8217;articolo sul PSR-1</a>.</p>



<h2 class="wp-block-heading">PSR-3: specifiche</h2>



<h3 class="wp-block-heading">LoggerInterface: l&#8217;Interfaccia di base</h3>



<p class="wp-block-paragraph">La <code class="" data-line="">&lt;strong&gt;&lt;em&gt;LoggerInterface&lt;/em&gt;&lt;/strong&gt;</code> <strong>espone otto metodi per scrivere i log</strong> utilizzando i rispettivi livelli dello standard<a href="http://tools.ietf.org/html/rfc5424"> RFC 5424</a>: debug, info, notice, warning, error, critical, alert, emergency. Tali livelli vengono definiti come costanti.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
&lt;?php

namespace Psr\Log;

class LogLevel
{
    const EMERGENCY = &#039;emergency&#039;;
    const ALERT     = &#039;alert&#039;;
    const CRITICAL  = &#039;critical&#039;;
    const ERROR     = &#039;error&#039;;
    const WARNING   = &#039;warning&#039;;
    const NOTICE    = &#039;notice&#039;;
    const INFO      = &#039;info&#039;;
    const DEBUG     = &#039;debug&#039;;
}

</pre></div>


<p class="wp-block-paragraph">Un <strong>nono metodo</strong> <em><code class="" data-line="">&lt;strong&gt;log&lt;/strong&gt;</code> </em><strong>accetta come primo argomento il livello di log</strong>. <br />La chiamata a questo metodo con una delle costanti di livello <strong>DEVE</strong> avere lo stesso effetto della chiamata al metodo specifico del relativo livello. Chiamare questo metodo con un livello non definito <strong>DEVE</strong> lanciare un&#8217;eccezione di tipo <code class="" data-line="">&lt;em&gt;Psr\Log\InvalidArgumentException&lt;/em&gt;</code> se l&#8217;implementazione non prevede tale livello. Gli utenti <strong>NON DOVREBBERO</strong> utilizzare un livello personalizzato senza essere certi che l&#8217;attuale implementazione lo supporti.</p>



<h3 class="wp-block-heading" id="LoggerInterface">Psr\Log\LoggerInterface: il codice</h3>



<p class="wp-block-paragraph">Di seguito il codice dell&#8217;interfaccia <a href="#LoggerInterface"><code class="" data-line="">&lt;strong&gt;&lt;em&gt;LoggerInterface&lt;/em&gt;&lt;/strong&gt;</code></a>.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
&lt;?php

namespace Psr\Log;

interface LoggerInterface
{
    /**
     * Il sistema è inutilizzabile
     *
     * @param string  $message
     * @param mixed&#x5B;] $context
     *
     * @return void
     */
    public function emergency( $message, array $context = &#x5B;] );

    /**
     * È necessario agire immediatamente.
     *
     * Esempio: Il sito web è down, database non disponibile, ... 
     *
     * @param string  $message
     * @param mixed&#x5B;] $context
     *
     * @return void
     */
    public function alert( $message, array $context = &#x5B;] );

    /**
     * Condizione critica
     *
     * Esepio: Componente non trovato, eccezione inaspettata, ...
     *
     * @param string  $message
     * @param mixed&#x5B;] $context
     *
     * @return void
     */
    public function critical( $message, array $context = &#x5B;] );

    /**
     * Errori di runtime che non richiedono un&#039;azione immediata 
     * ma in genere dovrebbero essere loggati e monitorati.
     *
     * @param string  $message
     * @param mixed&#x5B;] $context
     *
     * @return void
     */
    public function error( $message, array $context = &#x5B;] );

    /**
     * Occorrenze eccezionali che non sono errori
     * Esempio: uso di api deprecate.
     *
     * @param string  $message
     * @param mixed&#x5B;] $context
     *
     * @return void
     */
    public function warning( $message, array $context = &#x5B;] );

    /**
     * Eventi normali ma significativi.
     *
     * @param string  $message
     * @param mixed&#x5B;] $context
     *
     * @return void
     */
    public function notice( $message, array $context = &#x5B;] );

    /**
     * Eventi interessanti
     * Esempio: Log-in utente, esecuzione query, ...
     *
     * @param string  $message
     * @param mixed&#x5B;] $context
     *
     * @return void
     */
    public function info( $message, array $context = &#x5B;] );

    /**
     * Informazioni dettagliate sul debug.
     *
     * @param string  $message
     * @param mixed&#x5B;] $context
     *
     * @return void
     */
    public function debug( $message, array $context = &#x5B;] );

    /**
     * Creazione del Log con un livello arbitrario.
     *
     * @param mixed   $level
     * @param string  $message
     * @param mixed&#x5B;] $context
     *
     * @return void
     *
     * @throws \Psr\Log\InvalidArgumentException
     */
    public function log( $level, $message, array $context = &#x5B;] );
}
</pre></div>


<p class="wp-block-paragraph">La gestione dell&#8217;eccezione di <code class="" data-line="">&lt;em&gt;Psr\Log\InvalidArgumentException&lt;/em&gt;</code> estende la classe nativa di php <code class="" data-line="">&lt;a rel=&quot;noreferrer noopener&quot; href=&quot;https://www.php.net/manual/en/class.invalidargumentexception.php&quot; target=&quot;_blank&quot;&gt;&lt;em&gt;InvalidArgumentException&lt;/em&gt;&lt;/a&gt;</code> e deve essere lanciata dal logger qualora vengano passati ai metodi dei paramentri non corretti.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
&lt;?php

namespace Psr\Log;

class InvalidArgumentException extends \InvalidArgumentException {
    // class body
}
</pre></div>


<h3 class="wp-block-heading">PSR-3: messaggi</h3>



<p class="wp-block-paragraph"><strong>Ogni metodo accetta una stringa come messaggio</strong> o un oggetto con un metodo __toString (). Gli implementatori <strong>POSSONO implementare una gestione personalizzata per gli oggetti passati al metodo</strong>. In caso contrario, gli implementatori <strong>DEVONO eseguire il type casting del valore passato in stringa</strong>.</p>



<p class="wp-block-paragraph">Il messaggio <strong>PUÒ contenere un placeholder</strong> che gli implementatori possono sostituire con i valori presi dall&#8217;array del parametro context.</p>



<p class="wp-block-paragraph">I nomi dei <strong>placeholder DEVONO corrispondere alle chiavi del context array</strong>.</p>



<p class="wp-block-paragraph">I nomi dei <strong>placeholder DEVONO essere delimitati fra due parentesi graffe singole</strong> <code class="" data-line="">{placeholder}</code>. <strong>NON DEVE esserci spazio tra i delimitatori e il nome placeholder</strong>.<br /><br />I nomi dei <strong>placeholder DOVREBBERO essere composti solo dai caratteri <code class="" data-line="">A-Z</code>, <code class="" data-line="">a-z</code>, <code class="" data-line="">0-9</code>, underscore <code class="" data-line="">_</code>, e punto <code class="" data-line="">.</code></strong>. L&#8217;uso di altri caratteri è riservato per future modifiche delle specifiche dei placeholder.<br /><br />Gli implementatori POSSONO usare i placeholder per implementare <em>escaping strategy</em> o gestire la traduzione dei messagi. Gli utenti non DOVREBBERO effettuare l&#8217;escape preventivo dei placeholder poiché non possono sapere in quale contesto i dati inseriti nei messaggi verranno visualizzati.<br /><br />Il PHP-FIG fornisce una semplice funzione di esempio per comprendere meglio la funzione dei placeholder nei messaggi di log.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
&lt;?php

/**
 * Sostituisce i placeholder dei messaggi con i rispettivi valori.
 */
function interpolate($message, array $context = &#x5B;]) {
    // Crea l&#039;array delle sostituzioni
    $replace = array();
    foreach ($context as $key =&gt; $val) {
        // controlla che il valore possa essere usato come stringa.
        if (!is_array($val) &amp;&amp; (!is_object($val) || method_exists($val, &#039;__toString&#039;))) {
            $replace&#x5B;&#039;{&#039; . $key . &#039;}&#039;] = $val;
        }
    }

    // Sostituisce i placeholder con i rispettivi valori.
    return strtr($message, $replace);
}

// Messaggio contenente il placeholder fra graffe
$message = &quot;User {username} created&quot;;

// Il context array con i dati da sostituire ai placeholder
$context = array(&#039;username&#039; =&gt; &#039;bolivar&#039;);

// stampa &quot;User bolivar created&quot;
echo interpolate($message, $context);
</pre></div>


<h3 class="wp-block-heading">Context data</h3>



<p class="wp-block-paragraph">Ogni <strong>metodo accetta un array contenente dati contestuali (context data) per gestire ulteriori informazioni che non possano essere ridotte alla stringa del messagio</strong>. L&#8217;array può contenere qualsiasi tipo di dato. Gli implementatori <strong>DEVONO  utilizzare i dati di contesto con moderazione</strong>. Un context data <strong>NON DEVE generare un&#8217;eccezione né errori php</strong> di tipo error, warning o notice</p>



<p class="wp-block-paragraph">Se nei context data viene passato <strong>un oggetto di tipo <code class="" data-line="">&lt;em&gt;Exception&lt;/em&gt;</code>, questo DEVE essere passato nella chiave <code class="" data-line="">&#039;exception&#039;</code></strong>. Poiché il log delle eccezioni è un&#8217;esigenza diffusa, questa regola dello standard PSR-3 consente di registrare questo tipo di evento ed il relativo stack trace. Gli implementatori DEVONO verificare che il dato contenuto nella chiave <strong><code class="" data-line="">&#039;exception&#039;</code></strong> sia realmente <strong>un oggetto di tipo <code class="" data-line="">Exception</code></strong> dato che l&#8217;elemento dell&#8217;array potebbe contenere qualsiasi tipo di dato.</p>



<h2 class="wp-block-heading">PSR-3: classi helper ed interfacce</h2>



<p class="wp-block-paragraph">La classe di esempio <code class="" data-line="">&lt;em&gt;Psr\Log\AbstractLogger&lt;/em&gt;</code> facilita l&#8217;implementazione di <code class="" data-line="">&lt;em&gt;LoggerInterface&lt;/em&gt;</code> estendendola e implementando il metodo <code class="" data-line="">log</code> generico. Gli altri otto metodi richiamano il metodo <code class="" data-line="">&lt;em&gt;log&lt;/em&gt;</code> passandogli la corretta costante di livello, messaggio ed eventuale contesto.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
&lt;?php

namespace Psr\Log;

abstract class AbstractLogger implements LoggerInterface {

    public function emergency($message, array $context = &#x5B;]) {
        $this-&gt;log(LogLevel::EMERGENCY, $message, $context);
    }

    public function alert($message, array $context = &#x5B;]) {
        $this-&gt;log(LogLevel::ALERT, $message, $context);
    }

    public function critical($message, array $context = &#x5B;]) {
        $this-&gt;log(LogLevel::CRITICAL, $message, $context);
    }

    public function error($message, array $context = &#x5B;])) {
        $this-&gt;log(LogLevel::ERROR, $message, $context);
    }

    public function warning($message, array $context = &#x5B;]) {
        $this-&gt;log(LogLevel::WARNING, $message, $context);
    }

    public function notice($message, array $context = &#x5B;]) {
        $this-&gt;log(LogLevel::NOTICE, $message, $context);
    }

    public function info($message, array $context = &#x5B;]) {
        $this-&gt;log(LogLevel::INFO, $message, $context);
    }

    public function debug($message, array $context = &#x5B;]) {
        $this-&gt;log(LogLevel::DEBUG, $message, $context);
    }
}
</pre></div>


<p class="wp-block-paragraph">Similmente ad <code class="" data-line="">AbstractLogger</code> è possibile creare un trait <code class="" data-line="">&lt;em&gt;Psr\Log\LoggerTrait&lt;/em&gt;</code> utile nel caso si voglia implementare il logger in diverse classi. Poiché i traits non possono implementare delle interfacce, in questo caso si dovrà di fatto riscrivere il codice di <em>LoggerInterface</em>.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
namespace Psr\Log;

trait LoggerTrait {

    public function emergency($message, array $context = &#x5B;]) {
        $this-&gt;log(LogLevel::EMERGENCY, $message, $context);
    }

    public function alert($message, array $context = &#x5B;]) {
        $this-&gt;log(LogLevel::ALERT, $message, $context);
    }

    public function critical($message, array $context = array&#x5B;]) {
        $this-&gt;log(LogLevel::CRITICAL, $message, $context);
    }

    public function error($message, array $context = &#x5B;])) {
        $this-&gt;log(LogLevel::ERROR, $message, $context);
    }

    public function warning($message, array $context = &#x5B;]) {
        $this-&gt;log(LogLevel::WARNING, $message, $context);
    }

    public function notice($message, array $context = &#x5B;])
    {
        $this-&gt;log(LogLevel::NOTICE, $message, $context);
    }

    public function info($message, array $context = &#x5B;])
    {
        $this-&gt;log(LogLevel::INFO, $message, $context);
    }

    public function debug($message, array $context = &#x5B;])
    {
        $this-&gt;log(LogLevel::DEBUG, $message, $context);
    }

    abstract public function log($level, $message, array $context = &#x5B;]);
}
</pre></div>


<p class="wp-block-paragraph">Veniamo ora al &#8220;piuttosto che niente&#8221;! <code class="" data-line="">&lt;em&gt;Psr\Log\NullLogger&lt;/em&gt;</code> implementa  <code class="" data-line="">&lt;em&gt;AbstractLogger&lt;/em&gt;</code> e <strong>PUÒ</strong> essere usato dagli utenti, se non gli viene fornito un apposito log, da utilizzare con una fall-back. E&#8217; una sorta di &#8220;black hole&#8221; in cui inviare qualcosa che potrà essere loggato.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
&amp;lt;?php

namespace Psr\Log;

class NullLogger extends AbstractLogger
{
    /**
     * Logs with an arbitrary level.
     *
     * @param mixed  $level
     * @param string $message
     * @param array  $context
     *
     * @return void
     *
     * @throws \Psr\Log\InvalidArgumentException
     */
    public function log($level, $message, array $context = array())
    {
        // class body
    }
}
</pre></div>


<p class="wp-block-paragraph"><code class="" data-line="">&lt;em&gt;Psr\Log\LoggerAwareInterface&lt;/em&gt;</code> contiene solo un metodo <code class="" data-line="">setLogger(LoggerInterface $logger)</code> che <strong>PUÒ</strong> essere utilizzato dai framework per collegarsi automaticamente a istanze del logger.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
&amp;lt;?php

namespace Psr\Log;

interface LoggerAwareInterface {
    public function setLogger(LoggerInterface $logger);
}
</pre></div>


<p class="wp-block-paragraph">Il trait <code class="" data-line="">Psr\Log\LoggerAwareTrait</code> <strong>PUÒ</strong> essere utilizzato per implementare facilmente la medesima interfaccia in qualsiasi classe così da avere accesso all&#8217;oggetto <code class="" data-line="">$this-&gt;logger</code>.</p>



<h2 class="wp-block-heading">PSR-3 Logger package</h2>



<p class="wp-block-paragraph">Le interfacce e le classi descritte, nonché le relative classi di eccezione e una suite di test per verificare l&#8217;implementazione sono fornite come parte del pacchetto <a href="https://packagist.org/packages/psr/log" target="_blank" rel="noreferrer noopener">psr/log</a> sul sito ufficiale di PHP-FIG</p>
<p>L'articolo <a href="https://cesarebordi.it/psr-3-logger-interface-standard-log-php/">PSR-3 Logger Interface: standard log per PHP</a> sembra essere il primo su <a href="https://cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://cesarebordi.it/psr-3-logger-interface-standard-log-php/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
