<?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>PHP Archivi - Cesare Bordi | Innovation Manager &amp; Back-end Developer</title>
	<atom:link href="https://www.cesarebordi.it/category/categorie/php/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.cesarebordi.it/category/categorie/php/</link>
	<description>Innovare con soluzioni software efficaci e gioco di squadra</description>
	<lastBuildDate>Sat, 22 Apr 2023 08:03:29 +0000</lastBuildDate>
	<language>it-IT</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.4.2</generator>

<image>
	<url>https://www.cesarebordi.it/wp-content/uploads/2016/02/CB-logo-88x88.png</url>
	<title>PHP Archivi - Cesare Bordi | Innovation Manager &amp; Back-end Developer</title>
	<link>https://www.cesarebordi.it/category/categorie/php/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Design Pattern Builder in Php</title>
		<link>https://www.cesarebordi.it/design-pattern-builder-php/</link>
					<comments>https://www.cesarebordi.it/design-pattern-builder-php/#respond</comments>
		
		<dc:creator><![CDATA[cesarebordi]]></dc:creator>
		<pubDate>Fri, 14 Apr 2023 18:07:24 +0000</pubDate>
				<category><![CDATA[Lezioni]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[classi]]></category>
		<category><![CDATA[contro]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[esempio]]></category>
		<category><![CDATA[guida]]></category>
		<category><![CDATA[metodo]]></category>
		<category><![CDATA[oggetti]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[pro]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[programmazione ad oggetti]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[singleton]]></category>
		<guid isPermaLink="false">https://www.cesarebordi.it/?p=1476</guid>

					<description><![CDATA[<p>Il builder è un design pattern creazionale molto utilizzato. Vediamo come implementarlo in php.</p>
<p>L'articolo <a href="https://www.cesarebordi.it/design-pattern-builder-php/">Design Pattern Builder in Php</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Il builder fa parte dei <a href="https://www.cesarebordi.it/design-pattern-gof-guida/" target="_blank" rel="noreferrer noopener">design pattern creazionali</a>, vediamo come <strong>implementarlo correttamente in PHP</strong> partendo dalla definizione data dalla <a href="https://it.wikipedia.org/wiki/Design_Patterns" target="_blank" rel="noreferrer noopener">Gang of Four</a> (GoF).</p>



<blockquote class="wp-block-quote">
<p>Il <strong>Builder pattern</strong> separa la costruzione di un oggetto complesso dalla sua rappresentazione, così che il processo di costruzione possa creare rappresentazioni diverse.</p>
</blockquote>



<p>Il design pattern Builder è un pattern creazionale che viene utilizzato per creare oggetti complessi step by step. Il suo obiettivo principale è quello di separare la costruzione di un oggetto complesso dalla sua rappresentazione, in modo che lo stesso processo di costruzione possa essere utilizzato per creare oggetti differenti.</p>



<p>Il pattern Builder prevede l&#8217;utilizzo dei seguenti elementi:</p>



<ul>
<li><strong>Oggetto Builder</strong> che viene utilizzato per definire le caratteristiche generali e comuni di oggetti omogenei.</li>



<li><strong>Metodi di &#8220;costruzione&#8221;</strong> che permettono di definire nello specifico l&#8217;oggetto finale passo dopo passo.</li>
</ul>



<h2 class="wp-block-heading">Scenari di utilizzo</h2>



<p>Il <strong>pattern Builder </strong>può essere utilizzato ovunque ci sia la necessità di creare oggetti complessi in modo flessibile e modulare, e dove i passaggi di costruzione possono essere suddivisi in metodi più piccoli e gestibili.</p>



<p>Esempi concreti di impiego possono essere:</p>



<ul>
<li><strong>Creazione di oggetti Model</strong>: Il pattern Builder può essere utilizzato per creare oggetti Model complessi passo dopo passo. Ad esempio, se si vuole creare un oggetto Model che rappresenta un Ordine con molti dettagli, il pattern Builder può semplificare il processo di creazione dell&#8217;oggetto suddividendo i passaggi in metodi più piccoli e gestibili.</li>



<li><strong>Costruzione di Query</strong>: Il pattern Builder può essere utilizzato per costruire query SQL complesse in modo flessibile e modulare.</li>



<li><strong>Creazione di oggetti View</strong>: Il pattern Builder può essere utilizzato per creare oggetti View complessi passo dopo passo. </li>
</ul>



<h2 class="wp-block-heading">Esempio di pattern Builder in PHP</h2>



<p>Vediamo ora un <strong>esempio di codice in PHP</strong> che utilizza il pattern <strong>Builder</strong> per creare una classe che funga da <strong>query builder SQL</strong>.</p>



<pre class="wp-block-prismatic-blocks"><code class="language-php">class QueryBuilder {
  private $table;
  private $fields = array();
  private $conditions = array();

  public function table($table) {
    $this-&gt;table = $table;
    return $this;
  }

  public function select($fields) {
    $this-&gt;fields = $fields;
    return $this;
  }

  public function where($field, $operator, $value) {
    $this-&gt;conditions[] = array(
      &#039;field&#039; =&gt; $field,
      &#039;operator&#039; =&gt; $operator,
      &#039;value&#039; =&gt; $value
    );
    return $this;
  }

  public function build() {
    $query = &#039;SELECT &#039; . implode(&#039;, &#039;, $this-&gt;fields) . &#039; FROM &#039; . $this-&gt;table;
    if (!empty($this-&gt;conditions)) {
      $query .= &#039; WHERE &#039;;
      foreach ($this-&gt;conditions as $condition) {
        $query .= $condition[&#039;field&#039;] . &#039; &#039; . $condition[&#039;operator&#039;] . &#039; &#039; . $condition[&#039;value&#039;] . &#039; AND &#039;;
      }
      $query = rtrim($query, &#039; AND &#039;);
    }
    return $query;
  }
}</code></pre>



<p>In questo esempio, la classe QueryBuilder definisce i metodi per creare una query SQL complessa passo dopo passo. Il metodo <code>table</code> imposta la tabella su cui effettuare la query, il metodo <code>select</code> imposta i campi da selezionare, e il metodo <code>where</code> aggiunge una condizione alla clausola WHERE della query. Infine, il metodo <code>build</code> restituisce la query SQL completa.</p>



<p>Vediamo ora come utilizzare il query builder appena creato:</p>



<pre class="wp-block-prismatic-blocks"><code class="language-php">$query = (new QueryBuilder())
          -&gt;table(&#039;products&#039;)
          -&gt;select(array(&#039;id&#039;, &#039;name&#039;, &#039;price&#039;))
          -&gt;where(&#039;price&#039;, &#039;&gt;&#039;, 10)
          -&gt;where(&#039;category&#039;, &#039;=&#039;, &#039;electronics&#039;)
          -&gt;build();
echo $query;
// Output: SELECT id, name, price FROM products WHERE price &gt; 10 AND category = &#039;electronics&#039;

</code></pre>



<p>Nell&#8217;esempio di utilizzo, si crea un oggetto QueryBuilder<strong> </strong>e si chiamano i metodi necessari per costruire la query desiderata, ovvero selezionare l&#8217;id, il nome e il prezzo dei prodotti con un prezzo maggiore di 10 e appartenenti alla categoria &#8216;electronics&#8217;. Infine, si chiama il metodo <code>build</code> per ottenere la query SQL completa.</p>



<h2 class="wp-block-heading">Vantaggi del design pattern builder</h2>



<ul>
<li>Consente di <strong>creare oggetti complessi</strong> step by step, separando la costruzione dell&#8217;oggetto dalla sua rappresentazione e facilitando il processo di creazione.</li>



<li>Permette di <strong>creare oggetti con diverse configurazioni</strong>, utilizzando gli stessi passaggi di costruzione.</li>



<li>Consente di <strong>creare oggetti in modo più flessibile e modulare</strong>, aggiungendo o rimuovendo passaggi di costruzione a seconda delle necessità.</li>



<li>Consente di <strong>migliorare la leggibilità del codice</strong>, in particolare quando si hanno molti parametri da passare al costruttore.</li>
</ul>



<h2 class="wp-block-heading">Svantaggi del design pattern builder</h2>



<ul>
<li>Può <strong>aumentare la complessità del codice</strong>, in particolare se si hanno molti passaggi di costruzione da definire.</li>



<li>Può <strong>richiedere l&#8217;implementazione di molte classi aggiuntive</strong> (interfacce e classi concrete).</li>



<li>Può <strong>introdurre un costo aggiuntivo di tempo di esecuzione</strong> a causa dell&#8217;utilizzo di oggetti intermedi durante il processo di costruzione.</li>
</ul>



<h2 class="wp-block-heading">Conclusioni</h2>



<p>Il pattern Builder è un pattern molto utile e flessibile per la creazione di oggetti complessi, ma deve essere utilizzato con cautela e valutando attentamente le specifiche esigenze del progetto.</p>



<p>Per un panoramica generale sui design pattern consiglio di leggere l&#8217;<a href="https://www.cesarebordi.it/design-pattern-gof-guida/">articolo introduttivo sui <strong>design patterns</strong></a>.</p>
<p>L'articolo <a href="https://www.cesarebordi.it/design-pattern-builder-php/">Design Pattern Builder in Php</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.cesarebordi.it/design-pattern-builder-php/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Design Pattern Strategy in Php</title>
		<link>https://www.cesarebordi.it/design-pattern-strategy-php/</link>
					<comments>https://www.cesarebordi.it/design-pattern-strategy-php/#respond</comments>
		
		<dc:creator><![CDATA[cesarebordi]]></dc:creator>
		<pubDate>Wed, 22 Mar 2023 08:43:26 +0000</pubDate>
				<category><![CDATA[Lezioni]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[classi]]></category>
		<category><![CDATA[contro]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[esempio]]></category>
		<category><![CDATA[guida]]></category>
		<category><![CDATA[metodo]]></category>
		<category><![CDATA[oggetti]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[pro]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[programmazione ad oggetti]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[strategy]]></category>
		<guid isPermaLink="false">https://www.cesarebordi.it/?p=1427</guid>

					<description><![CDATA[<p>Lo strategy è tra i design pattern comportamentali più utilizzati. Permette di definire algoritmi e renderli interscambiabili. Vediamo come implementarlo in php.</p>
<p>L'articolo <a href="https://www.cesarebordi.it/design-pattern-strategy-php/">Design Pattern Strategy in Php</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Lo <strong>strategy</strong> è tra i <a href="https://www.cesarebordi.it/design-pattern-gof-guida/" target="_blank" rel="noreferrer noopener">design pattern comportamentali</a> più utilizzati nella <strong>programmazione ad oggetti</strong> (<strong>OOP</strong>) soprattutto in approcci <strong>MVC.</strong><br />Vediamo come <strong>implementarlo correttamente in PHP</strong> partendo dalla definizione data dalla <a href="https://it.wikipedia.org/wiki/Design_Patterns" target="_blank" rel="noreferrer noopener">Gang of Four</a> (GoF).</p>



<blockquote class="wp-block-quote">
<p>Lo <strong>Strategy pattern</strong> definisce una famiglia di algoritmi, li incapsula e li rende interscambiabili tra di loro. Strategy permette di variare gli algoritmi indipendentemente dai client che li usano.</p>
</blockquote>



<p>Il <strong>design pattern Strategy</strong> è utile quando si desidera selezionare l&#8217;algoritmo da utilizzare in fase di esecuzione ed è composto da tre elementi fondamentali:</p>



<ul>
<li>L&#8217;<strong>interfaccia o la classe astratta &#8220;Strategy&#8221;</strong>: definisce il contratto che deve essere implementato dalle classi che rappresentano le diverse strategie di algoritmo. L&#8217;interfaccia o la classe astratta può includere un o più metodi, che rappresentano le operazioni che l&#8217;algoritmo deve essere in grado di eseguire.</li>



<li>Le <strong>classi concrete delle strategie</strong>: queste classi implementano l&#8217;interfaccia o la classe astratta &#8220;Strategy&#8221; e rappresentano le diverse implementazioni degli algoritmi.</li>



<li>La <strong>classe &#8220;Context&#8221;</strong>: rappresenta il contesto in cui viene eseguito l&#8217;algoritmo e che utilizza una delle strategie disponibili per l&#8217;esecuzione. La classe &#8220;Context&#8221; deve accettare un&#8217;istanza di una delle classi concrete delle strategie attraverso il costruttore e/o un metodo setter.</li>
</ul>



<h2 class="wp-block-heading">Scenario di utilizzo</h2>



<p>Il <strong>desgin pattern Strategy</strong> è utile in situazioni in cui è necessario avere la possibilità di cambiare il comportamento di un&#8217;operazione in modo flessibile e senza dover modificare il codice dell&#8217;operazione stessa.</p>



<p>Esempi concreti di impiego possono essere:</p>



<ul>
<li><strong>Nel controller di un framework MVC</strong>, è possibile utilizzare il pattern Strategy per incapsulare la logica di business associata a un&#8217;azione specifica. Ad esempio, se un&#8217;azione richiede la validazione dei dati di input, è possibile utilizzare una classe di validazione Strategy per gestire questo compito in modo indipendente dalla logica di business principale.</li>



<li><strong>Nel modello di un framework MVC</strong>, è possibile utilizzare il pattern Strategy per gestire la connessione ai diversi database utilizzati dall&#8217;applicazione. In questo modo, è possibile rendere la scelta del database dinamica e intercambiabile a runtime.</li>



<li><strong>Nel template di un framework MVC</strong>, è possibile utilizzare il pattern Strategy per definire diverse strategie di rendering a seconda del tipo di visualizzazione richiesta. Ad esempio, è possibile utilizzare una classe di rendering HTML per le visualizzazioni web e una classe di rendering JSON per le API REST.</li>
</ul>



<h2 class="wp-block-heading">Esempio di pattern Strategy in PHP</h2>



<p>Supponiamo di dover calcolare il prezzo di un prodotto in un negozio online, ma il prezzo può variare in base a diversi fattori, come il tipo di sconto, le imposte applicabili e le tariffe di spedizione.</p>



<p>Invece di creare un metodo per ogni combinazione possibile di fattori, possiamo utilizzare il design pattern Strategy per creare un insieme di algoritmi, o strategie, che possono essere scelti in fase di esecuzione in base ai fattori specifici.</p>



<p>Vediamo ora il codice di base per <strong>implementare</strong> questo pattern.</p>



<pre class="wp-block-prismatic-blocks"><code class="language-php">// Creazione dell&#039;interfaccia della strategia
interface PricingStrategy {
    public function calculatePrice($product);
}

// Implementazione della prima strategia: nessuno sconto
class NoDiscountStrategy implements PricingStrategy {
    public function calculatePrice($product) {
        return $product-&gt;getPrice();
    }
}

// Implementazione della seconda strategia: sconto del 10%
class TenPercentDiscountStrategy implements PricingStrategy {
    public function calculatePrice($product) {
        return $product-&gt;getPrice() * 0.9;
    }
}

// Implementazione della terza strategia: sconto del 20%
class TwentyPercentDiscountStrategy implements PricingStrategy {
    public function calculatePrice($product) {
        return $product-&gt;getPrice() * 0.8;
    }
}

// Implementazione della classe prodotto
class Product {
    private $price;
    private $pricingStrategy;
    
    public function __construct($price, $pricingStrategy) {
        $this-&gt;price = $price;
        $this-&gt;pricingStrategy = $pricingStrategy;
    }
    
    public function getPrice() {
        return $this-&gt;pricingStrategy-&gt;calculatePrice($this);
    }
    
    public function setPricingStrategy($pricingStrategy) {
        $this-&gt;pricingStrategy = $pricingStrategy;
    }
}

// Utilizzo del codice
$product = new Product(100, new NoDiscountStrategy());
echo $product-&gt;getPrice(); // output: 100

$product-&gt;setPricingStrategy(new TenPercentDiscountStrategy());
echo $product-&gt;getPrice(); // output: 90

$product-&gt;setPricingStrategy(new TwentyPercentDiscountStrategy());
echo $product-&gt;getPrice(); // output: 80</code></pre>



<p>In questo esempio, abbiamo creato un&#8217;interfaccia <code>PricingStrategy</code> che definisce un metodo <code>calculatePrice()</code>, che viene implementato dalle classi <code>NoDiscountStrategy</code>, <code>TenPercentDiscountStrategy</code> e <code>TwentyPercentDiscountStrategy</code>.</p>



<p>Abbiamo quindi creato una classe <code>Product</code> che accetta un oggetto <code>PricingStrategy</code> nel suo costruttore e ha un metodo <code>getPrice()</code> che utilizza la strategia selezionata per calcolare il prezzo del prodotto.</p>



<p>Infine, abbiamo creato un oggetto <code>Product</code> con un prezzo di 100 e senza sconto, e abbiamo utilizzato il metodo <code>setPricingStrategy()</code> per selezionare le altre strategie di sconto e calcolare il prezzo del prodotto in base ad esse.</p>



<h2 class="wp-block-heading">Vantaggi del design pattern strategy</h2>



<ul>
<li>Consente di isolare la logica di business in classi separate, rendendo il codice più modulare e facile da testare.</li>



<li>Permette di sostituire gli algoritmi utilizzati in modo semplice e senza dover modificare il codice esistente.</li>



<li>Favorisce l&#8217;estendibilità del codice, poiché nuovi algoritmi possono essere facilmente aggiunti senza dover modificare la struttura esistente.</li>
</ul>



<h2 class="wp-block-heading">Svantaggi del design pattern strategy</h2>



<ul>
<li>L&#8217;uso del pattern Strategy può portare a un aumento della complessità del codice, poiché richiede la creazione di molte classi aggiuntive.</li>



<li>Il pattern Strategy potrebbe non essere necessario in tutti i casi e potrebbe rappresentare una soluzione eccessiva in alcune situazioni.</li>
</ul>



<h2 class="wp-block-heading">Conclusioni</h2>



<p>Il design pattern Strategy può essere una soluzione potente per creare codice modulare e flessibile, ma deve essere utilizzato con cautela e solo quando è effettivamente necessario.</p>



<p>Per un panoramica generale consiglio di leggere l&#8217;<a href="https://www.cesarebordi.it/design-pattern-gof-guida/">articolo introduttivo sui <strong>design patterns</strong></a>.</p>
<p>L'articolo <a href="https://www.cesarebordi.it/design-pattern-strategy-php/">Design Pattern Strategy in Php</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.cesarebordi.it/design-pattern-strategy-php/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>PSR-7 Http Message: standard php per Request e Response.</title>
		<link>https://www.cesarebordi.it/psr-7-http-message-standard-php-request-response/</link>
					<comments>https://www.cesarebordi.it/psr-7-http-message-standard-php-request-response/#respond</comments>
		
		<dc:creator><![CDATA[cesarebordi]]></dc:creator>
		<pubDate>Wed, 23 Sep 2020 07:27:42 +0000</pubDate>
				<category><![CDATA[Lezioni]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[best practice]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php-fig]]></category>
		<category><![CDATA[phpfig]]></category>
		<category><![CDATA[psr]]></category>
		<category><![CDATA[psr-7]]></category>
		<category><![CDATA[psr7]]></category>
		<category><![CDATA[standard]]></category>
		<category><![CDATA[web developer]]></category>
		<category><![CDATA[webservice]]></category>
		<guid isPermaLink="false">https://www.cesarebordi.it/?p=1273</guid>

					<description><![CDATA[<p>PSR-7 Http Message del PHP-FIG propone interfacce php standard per rappresentare i messaggi Http di Request e Response.</p>
<p>L'articolo <a href="https://www.cesarebordi.it/psr-7-http-message-standard-php-request-response/">PSR-7 Http Message: standard php per Request e Response.</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p><strong>PSR-7 Http Message</strong> del PHP-FIG propone interfacce <strong>php</strong> standard per rappresentare i <strong>messaggi Http</strong> di <strong>Request</strong> e <strong>Response</strong> oltre ad analizzarne il contenuto.</p>



<blockquote class="wp-block-quote"><p>HTTP messages are the foundation of web development.</p></blockquote>



<p>Standardizzare questo aspetto è importantissimo poiché i messaggi Http sono le fondamenta dello sviluppo web. I browser ed i client come cURL inviano <strong>richieste Http</strong> al server che fornisce un&#8217;adeguata <strong>risposta Http</strong>.</p>



<p>Di seguito analizzeremo le interfacce proposte dal <a href="https://www.php-fig.org/psr/psr-7/" target="_blank" rel="noreferrer noopener">PSR-7</a> che rappresentano astrazioni dei messaggi Http e degli elementi che li compongono. Per il significato delle parole chiave presenti nell&#8217;articolo si rimanda alle <a href="https://www.cesarebordi.it/psr-1-regole-scrittura-codice-php/#note" target="_blank" rel="noreferrer noopener">note dell’articolo sul PSR-1</a>.</p>



<h2 class="wp-block-heading">Http Request</h2>



<p>Iniziamo esaminando il contenuto di una <strong>Http Request</strong>.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
POST /path HTTP/1.1
Host: example.com

foo=bar&amp;baz=bat
</pre></div>


<p>La prima riga,  detta &#8220;request line&#8221;, contiene il <strong>metodo della richiesta Http</strong>, il <strong>target della richiesta Http</strong>, solitamente una URI assoluta o un percorso sul server web, la <strong>versione del protocollo Http</strong> utilizzato. A questo seguono una o più <strong>intestazioni Http</strong>, una riga vuota ed il <strong>corpo del messaggio</strong>.</p>



<h2 class="wp-block-heading">Http Response</h2>



<p>Esaminiamo ora il contenuto di una <strong>Http Response</strong>.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; gutter: false; title: ; notranslate">
HTTP/1.1 200 OK
Content-Type: text/plain

This is the response body
</pre></div>


<p>La prima riga di una <strong>Http Response</strong>, detta &#8220;status line&#8221;, contiene la <strong>versione del protocollo Http</strong>, il <strong>codice di stato Http</strong> ed una <strong>descrizione comprensibile</strong> del codice di stato. Come per il messaggio di richiesta, questa riga è seguita da una o più <strong>intestazioni Http</strong>, una riga vuota ed il <strong>corpo del messaggio</strong>.</p>



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



<h3 class="wp-block-heading">Messaggi Http</h3>



<p>Un <strong>messaggio Http</strong> è una richiesta da un client ad un server o una risposta da un server ad un client. PSR-7 definisce le rispettive interfacce per i messaggi Http: <strong><em><code>Psr\Http\Message\RequestInterface</code></em></strong> e <strong><em><code>Psr\Http\Message\ResponseInterface</code></em></strong>.</p>



<p>Entrambe estendono <strong><em><code>Psr\Http\Message\MessageInterface</code></em></strong>.<br />Mentre <strong><em><code>&lt;a href=&quot;#MessageInterface&quot;&gt;Psr\Http\Message\MessageInterface&lt;/a&gt;</code></em></strong> <strong>PUÒ essere implementato</strong> direttamente, gli implementatori <strong>DOVREBBERO implementare</strong> <strong><em><code>Psr\Http\Message\RequestInterface</code></em></strong> e <strong><em><code>Psr\Http\Message\ResponseInterface</code></em></strong>.<br />Per migliorare la lettura dell&#8217;articolo, da qui in avanti verrà omesso il namespace <em><code>Psr\Http\Message</code></em> per riferirsi a queste interfacce.</p>



<h3 class="wp-block-heading">HTTP Headers</h3>



<h4 class="wp-block-heading">Nomi case-insensitive nei campi di intestazione.</h4>



<p>I <strong>messaggi Http</strong> possono includere vari campi nell&#8217;intestazione (header) <strong>senza distinzione tra maiuscole e minuscole</strong>. Allo stesso modo dovranno essere recuperate dalle classi che implementano <code>&lt;strong&gt;&lt;em&gt;&lt;a href=&quot;#MessageInterface&quot;&gt;MessageInterface&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;</code>. <br />Ad esempio, il recupero dell&#8217;intestazione <code>foo</code> restituirà lo stesso risultato del recupero dell&#8217;intestazione <code>FoO</code>. Allo stesso modo, l&#8217;impostazione dell&#8217;intestazione <code>Foo</code> sovrascriverà qualsiasi valore di intestazione <code>foo</code> precedentemente impostato.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
$message = $message-&gt;withHeader('foo', 'bar');

echo $message-&gt;getHeaderLine('foo');
// Outputs: bar

echo $message-&gt;getHeaderLine('FOO');
// Outputs: bar

$message = $message-&gt;withHeader('fOO', 'baz');

echo $message-&gt;getHeaderLine('foo');
// Outputs: baz
</pre></div>


<p>Nonostante le intestazioni possano essere recuperate senza distinzione tra maiuscole e minuscole, <strong>il case originale DEVE essere rispettato</strong> nell&#8217;implementazione, in particolar modo quando viene recuperato con <code>getHeaders()</code>. Questo perché applicazioni Http non conformi possono dipendere da un determinato caso.</p>



<h4 class="wp-block-heading">Campi di intestazione con valori multipli</h4>



<p>Per gestire campi di intestazione con più valori e fornire una migliore flessibilità nella gestione, le intestazioni possono essere recuperate da un&#8217;istanza di <code>&lt;strong&gt;&lt;em&gt;MessageInterface&lt;/em&gt;&lt;/strong&gt;</code> come array o stringa. Nel primo caso useremo <code>&lt;strong&gt;getHeader()&lt;/strong&gt;</code>, nel secondo <code>&lt;strong&gt;getHeaderLine()&lt;/strong&gt;</code>. </p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
$message = $message
    -&gt;withHeader('foo', 'bar')
    -&gt;withAddedHeader('foo', 'baz');

$header = $message-&gt;getHeaderLine('foo');
// $header contiene: 'bar,baz'

$header = $message-&gt;getHeader('foo');
// &#x5B;'bar', 'baz']
</pre></div>


<p>Da notare che non tutti i valori di intestazione possono essere concatenati con la virgola (es: Set-Cookie). In questo caso gli utilizzatori <strong>DOVREBBERO usare metodo <code>getHeader()</code></strong> per recuperare tali intestazioni multivalore.</p>



<h4 class="wp-block-heading">Intestazione &#8220;Host&#8221;</h4>



<p>Nelle richieste, l&#8217;intestazione <code>Host</code> riporta l&#8217;host dell&#8217;URI, nonché l&#8217;host utilizzato per stabilire la connessione Tcp. Le specifiche del protocollo Http consentono però all&#8217;intestazione <code>Host</code> di differire da entrambi. Le implementazioni, se non viene fornita alcuna intestazione <code>Host</code>, <strong>DEVONO tentare di impostarla da un URI predefinito</strong> .</p>



<p><code>&lt;strong&gt;RequestInterface :: withUri (UriInterface $uri, $preserveHost = false)&lt;/strong&gt;</code>, per impostazione predefinita, sostituirà l&#8217;intestazione Host della richiesta restituita con quella dell&#8217;oggetto di tipo <code>&lt;strong&gt;UriInterface&lt;/strong&gt;</code> passatogli. Per mantenere il valore originale basterà passare <code>true</code> al secondo argomento (<code>$preservHost</code>). Ciò manterrà invariata l&#8217;intestazione Host a patto che il messaggio ne contenga una.</p>



<p>Questa tabella mostra cosa restituirà <code>getHeaderLin(&#039;Host&#039;)</code> per una richiesta restituita da <code>withUri()</code> con l&#8217;argomento <code>$preservHost</code> impostato su <code>true</code> in varie richieste iniziali e URI.</p>



<table>
  <thead>
    <tr>
      <th>Request Host header<sup>1</sup></th>
      <th>Request host component<sup>2</sup></th>
      <th>URI host component<sup>3</sup></th>
      <th>Result</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>’’</td>
      <td>’’</td>
      <td>’’</td>
      <td>’’</td>
    </tr>
    <tr>
      <td>’’</td>
      <td>foo.com</td>
      <td>’’</td>
      <td>foo.com</td>
    </tr>
    <tr>
      <td>’’</td>
      <td>foo.com</td>
      <td>bar.com</td>
      <td>foo.com</td>
    </tr>
    <tr>
      <td>foo.com</td>
      <td>’’</td>
      <td>bar.com</td>
      <td>foo.com</td>
    </tr>
    <tr>
      <td>foo.com</td>
      <td>bar.com</td>
      <td>baz.com</td>
      <td>foo.com</td>
    </tr>
  </tbody>
</table>



<ol><li>Valore dell&#8217;intestazione host prima dell&#8217;operazione.</li><li>Componente host dell&#8217;URI composto nella richiesta prima dell&#8217;operazione.</li><li>Componente host dell&#8217;URI settato tramite <code>withUri()</code>.</li></ol>



<h3 class="wp-block-heading">Streams</h3>



<p>I messaggi Http sono costituiti da una riga iniziale, alcune intestazioni ed un corpo che può essere anche molto grande. Rappresentare il body di un messaggio come una stringa potrebbe consumare molta memoria fino a precludere la possibiltà di lavorare con body di grandi dimensioni. <code>&lt;strong&gt;StreamInterface&lt;/strong&gt;</code> viene utilizzato proprio per nascondere i dettagli di implementazione quando un flusso di dati viene letto o scritto. Per le situazioni in cui una stringa sarebbe un&#8217;implementazione del messaggio appropriata, è possibile utilizzare flussi incorporati come <code>php://memory</code> e <code>php://temp</code>.<br /><br /><strong><code>StreamInterface</code></strong> espone diversi metodi che consentono di leggere, scrivere e scorrere gli stream in modo efficace.<br /><br />Gli stram espongono le loro capacità utilizzando tre metodi: <strong><code>isReadable()</code></strong>, <code>&lt;strong&gt;isWritable()&lt;/strong&gt;</code> e <code>&lt;strong&gt;isSeekable()&lt;/strong&gt;</code>. Gli oggetti che vogliono utilizzare uno stream possono utilizzare questi metodi per determinare se è in grado di soddisfare determinati requisiti.<br /><br />Ogni istanza di uno stream avrà diverse funzionalità: può essere di sola lettura, di sola scrittura o di lettura/scrittura. Può consentire un accesso casuale arbitrario (ricerca in avanti o indietro in qualsiasi posizione) o solo accesso sequenziale come nel caso di socket, pipe, o callback-based stream.<br /><br />Infine, <strong><code>StreamInterface</code></strong> definisce un metodo <strong><code>__toString()</code></strong> per recuperare o inviare l&#8217;intero contenuto del corpo in una sola volta.<br /><br />A differenza delle interfacce di Request e Response, <strong><code>StreamInterface</code></strong> interagisce con gli stream che, per loro natura, possono mutare durante il loro utilizzo. La raccomandazione di Php-Fig è di utilizzare flussi di sola lettura per le richieste lato server e le risposte lato client.</p>



<h3 class="wp-block-heading">Target della richiesta ed URI</h3>



<p>Secondo lo standard <a rel="noreferrer noopener" href="https://tools.ietf.org/html/rfc7230" target="_blank">RFC 7230</a> i messaggi di richiesta contengono uno dei seguenti tipi di &#8220;target&#8221;:</p>



<ul><li><strong>origin-form</strong>: costituito da <strong>percorso</strong> e, se presente, <strong>stringa della query</strong>. È solitamente definito come un URL relativo. I messaggi trasmessi via Tcp sono tipicamente di tipo <em>origin-form</em>; i dati di <em>scheme</em> e <em>authority</em> sono presenti tramite variabili CGI.</li><li><strong>absolute-form</strong>: costituito da <strong>scheme</strong>, <strong>authority</strong> (“[user-info@]host[:port]”, dove gli elementi tra parentesi sono facoltativi), <strong>percorso</strong> (se presente), <strong>stringa della query</strong> (se presente) e<strong> fragment</strong> ( se presente). È solitamente definito come un URI assoluto ed è l&#8217;unico che consente di specificare una URI come descritto nel <a rel="noreferrer noopener" href="https://tools.ietf.org/html/rfc3986" target="_blank">RFC 3986</a>. Questo modulo è comunemente usato quando si effettuano richieste ai proxy Http</li><li><strong>authority-form</strong>: costituito dalla sola <strong>authority.</strong> È solitamente utilizzato nelle CONNECT Request per stabilire una connessione tra un client Http e un server proxy.</li><li><strong>asterisk-form</strong>: costituito unicamente dalla <strong>stringa asterisco</strong> ( &#8221; * &#8221; ). È solitamente utilizzato con il <strong>metodo OPTIONS</strong> per determinare le capacità generali di un server web.</li></ul>



<p>Oltre a questi target di richiesta, c&#8217;è spesso un &#8220;URL effettivo&#8221; che è separato dal target di richiesta. L&#8217;URL effettivo non viene trasmesso all&#8217;interno di un messaggio Http, ma viene utilizzato per determinare il protocollo (http / https), la porta e l&#8217;host-name per effettuare la richiesta.</p>



<p>L&#8217;URL effettivo è rappresentato da <code>&lt;strong&gt;UriInterface&lt;/strong&gt;</code>. <code>UriInterface</code> rappresenta gli URI Http e Https fornendo i metodi per interagire con le varie parti dell&#8217;URI evitendo un&#8217;analisi ripetuta dell&#8217;URI. Specifica inoltre un metodo <code>__toString()</code> per rappresentare la URI come stringa.</p>



<p>Quando si recupera la destinazione della richiesta con <code>&lt;strong&gt;getRequestTarget()&lt;/strong&gt;</code>, per impostazione predefinita questo metodo utilizzerà l&#8217;oggetto URI ed estrarrà tutti i componenti necessari per costruire l&#8217;origin-form che è il request-target più comune.</p>



<p>Se si desidera utilizzare uno degli altri tre tipi di target o se l&#8217;utente desidera sovrascrivere esplicitamente il target della richiesta si utilizzerà il metodo <code>&lt;strong&gt;withRequestTarget()&lt;/strong&gt;</code>. La chiamata a questo metodo non influisce sull&#8217;URI, poiché viene restituito da <code>&lt;strong&gt;getUri()&lt;/strong&gt;</code>.</p>



<p>Ad esempio, un utente potrebbe voler effettuare una richiesta in formato asterisco a un server:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; gutter: false; title: ; notranslate">
$request = $request
    -&gt;withMethod('OPTIONS')
    -&gt;withRequestTarget('*')
    -&gt;withUri(new Uri('https://example.org/'));
</pre></div>


<p>L&#8217;esempio creerebbe questo tipo di richiesta Http:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
OPZIONI * HTTP / 1.1
</pre></div>


<p>Il client Http sarà poi in grado di utilizzare l&#8217;URL effettivo (<code>getUri()</code>) per determinare il protocollo, l&#8217;host-name e la porta Tcp.</p>



<p>Un client Http <strong>DEVE</strong> ignorare i valori di <code>&lt;strong&gt;Uri::getPath()&lt;/strong&gt;</code> e <code>&lt;strong&gt;Uri::getQuery()&lt;/strong&gt;</code> ed utilizzare il valore restituito da <code>&lt;strong&gt;getRequestTarget()&lt;/strong&gt;</code> che concatena questi due valori.</p>



<p>I client che scelgono di non implementare 1 o più dei 4 request-target form, <strong>DEVONO</strong> comunque utilizzare <code>&lt;strong&gt;getRequestTarget()&lt;/strong&gt;</code>. Questi client <strong>DEVONO</strong> rifiutare <strong>request-target</strong> che non supportano e <strong>NON DEVONO</strong> utilizzare i valori di <code>&lt;strong&gt;getUri()&lt;/strong&gt;</code>.</p>



<p><code>&lt;strong&gt;RequestInterface&lt;/strong&gt;</code> fornisce metodi per recuperare il target della richiesta o creare una nuova istanza specificando il target. Per impostazione predefinita, se non viene specificato il request-target, <code>&lt;strong&gt;getRequestTarget()&lt;/strong&gt;</code> restituirà l&#8217;origin-form della URI composta o &#8221; / &#8221; se non è stata composta una URI. <strong><code>withRequestTarget($requestTarget</code>)</strong> crea una nuova istanza con il request-target specificato ed è utile per creare connessioni verso un server.</p>



<h3 class="wp-block-heading">Richieste Server-side</h3>



<ul><li><code>&lt;strong&gt;RequestInterface&lt;/strong&gt;</code> permette di rappresentare un messaggio di richiesta Http, ma le richieste lato server side richiedono un&#8217;attenzione particolare. I processi server-side devono tener conto della Common Gateway Interface (CGI) e dell&#8217;interazione di PHP con essa attraverso le sue via Server API (SAPI) . PHP ci fornisce una semplificazione per la gestione degli input attraverso variabili superglobali:</li><li><code>&lt;strong&gt;$_COOKIE&lt;/strong&gt;</code>: deserializza e fornisce un accesso ai cookie Http.</li><li><code>&lt;strong&gt;$_GET&lt;/strong&gt;</code>: deserializza e fornisce un accesso agli argomenti della query string.</li><li><strong><code>$_POST</code></strong>: deserializza e fornisce un accesso per i parametri inviati tramite. Post Http. Può essere considerato il risultato dell&#8217;analisi del message body.</li><li><strong><code>$_FILES</code></strong>: fornisce metadati relativi ai caricamenti dei file.</li><li><strong><code>$_SERVER</code></strong>: fornisce l&#8217;accesso alle variabili d&#8217;ambiente CGI / SAPI che includono il metodo di richiesta, lo schema di richiesta, l&#8217;URI della richiesta e le intestazioni.</li></ul>



<p><strong><code>ServerRequestInterface</code></strong> estende <strong><code>RequestInterface</code></strong> per fornire un&#8217;astrazione su questi variabili superglobali riducendo l&#8217;accoppiamento.<br /><br />La richiesta server-side fornisce una proprietà aggiuntiva,  gli &#8220;attributi&#8221;, che consentono di esaminare, scompore e cercare match in modo da interpretare la richiesta in base alle specifiche necessità nell&#8217;applicativo.</p>



<h3 class="wp-block-heading">Upload dei file</h3>



<p><code>&lt;strong&gt;ServerRequestInterface&lt;/strong&gt;</code> specifica un metodo per recuperare una rappresentazione dei file caricati attraverso una struttura normalizzata in cui ogni elemento è un&#8217;istanza di <code>&lt;strong&gt;UploadedFileInterface&lt;/strong&gt;</code>.</p>



<p><strong><code>$_FILES</code></strong> ha alcuni problemi noti, ad esempio se si tenta di inviare da un form molteplici file attraverso campi di input aventi name &#8220;files&#8221;, l&#8217;array risultante verrà così rappresentato da PHP:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; gutter: false; title: ; notranslate">
array(
    'files' =&gt; array(
        'name' =&gt; array(
            0 =&gt; 'file0.txt',
            1 =&gt; 'file1.html',
        ),
        'type' =&gt; array(
            0 =&gt; 'text/plain',
            1 =&gt; 'text/html',
        ),
        /* etc. */
    ),
)
</pre></div>


<p>Mentre ci si aspetterebbe una rappresentazione di questo tipo:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; gutter: false; title: ; notranslate">
array(
    'files' =&gt; array(
        0 =&gt; array(
            'name' =&gt; 'file0.txt',
            'type' =&gt; 'text/plain',
            /* etc. */
        ),
        1 =&gt; array(
            'name' =&gt; 'file1.html',
            'type' =&gt; 'text/html',
            /* etc. */
        ),
    ),
)
</pre></div>


<p>Gli utilizzatori devono conoscere quindi i dettagli dell&#8217;implementazione nel linguaggio PHP e scrivere il codice per interpretare correttamente i dati di un determinato caricamento. </p>



<p>In alcuni casi poi <code>$_FILES</code> non viene popolato con i dati relativi ai file caricati:</p>



<ul><li>Quando il metodo Http non è POST.</li><li>Quando si esegue una unit test.</li><li>Quando si opera in un ambiente non SAPI come ad esempio ReactPHP.</li></ul>



<p>In questi casi si dovranno utilizzare approcci diversi, ad esempio:</p>



<ul><li>Un processo potrebbe analizzare il message body per scoprire i file caricati. </li><li>Negli scenari di unit test, gli sviluppatori devono essere in grado di bloccare e/o simulare i metadati di caricamento del file per convalidare e verificare i diversi scenari.</li></ul>



<p><code>&lt;strong&gt;getUploadedFiles()&lt;/strong&gt;</code> fornisce una struttura normalizzata e l&#8217;implementazione dovrebbe:</p>



<ul><li>Aggregare tutte le informazioni per un determinato caricamento di file e usarle per popolare un&#8217;istanza<code> &lt;strong&gt;Psr\Http\Message\UploadedFileInterface&lt;/strong&gt;</code>.</li><li>Ricreare la struttura ad albero inviata in cui ogni foglia rappresenti un&#8217;istanza di <code>&lt;strong&gt;Psr\Http\Message\UploadedFileInterface&lt;/strong&gt;</code> appropriata.</li><li>La struttura ad albero dovrebbe seguire la struttura dei nomi in cui sono stati inviati i file.</li></ul>



<p>Vediamo un esempio con un singolo campo di input con un &#8220;name semplice&#8221;:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: xml; gutter: false; title: ; notranslate">
&lt;input type=&quot;file&quot; name=&quot;avatar&quot; /&gt;
</pre></div>


<p>In questo caso, la struttura di $ _FILES sarebbe:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; gutter: false; title: ; notranslate">
array(
    'avatar' =&gt; array(
        'tmp_name' =&gt; 'phpUxcOty',
        'name' =&gt; 'my-avatar.png',
        'size' =&gt; 90996,
        'type' =&gt; 'image/png',
        'error' =&gt; 0,
    ),
)
</pre></div>


<p>Mentre la forma normalizzata restituita da <code>getUploadedFiles()</code> potrebbe essere:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; gutter: false; title: ; notranslate">
array(
    'avatar' =&gt; /* UploadedFileInterface instance */
)
</pre></div>


<p>Vediamo invece un caso di campo di input che utilizza crea un array nell&#8217;attributo nome:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: xml; gutter: false; title: ; notranslate">
&lt;input type=&quot;file&quot; name=&quot;my-form&#x5B;details]&#x5B;avatar]&quot; /&gt;
</pre></div>


<p>In questo caso il contenuto di $_FILES sarà</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; gutter: false; title: ; notranslate">
array (
    'my-form' =&gt; array (
        'name' =&gt; array (
            'details' =&gt; array (
                'avatar' =&gt; 'my-avatar.png',
            ),
        ),
        'type' =&gt; array (
            'details' =&gt; array (
                'avatar' =&gt; 'image/png',
            ),
        ),
        'tmp_name' =&gt; array (
            'details' =&gt; array (
                'avatar' =&gt; 'phpmFLrzD',
            ),
        ),
        'error' =&gt; array (
            'details' =&gt; array (
                'avatar' =&gt; 0,
            ),
        ),
        'size' =&gt; array (
            'details' =&gt; array (
                'avatar' =&gt; 90996,
            ),
        ),
    ),
)
</pre></div>


<p>E l&#8217;albero corrispondente restituito da <code>getUploadedFiles()</code> dovrebbe essere:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; gutter: false; title: ; notranslate">
array(
    'my-form' =&gt; array(
        'details' =&gt; array(
            'avatar' =&gt; /* UploadedFileInterface instance */
        ),
    ),
)
</pre></div>


<p>Vediamo ora il caso di un array di file:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: xml; gutter: false; title: ; notranslate">
Upload an avatar: &lt;input type=&quot;file&quot; name=&quot;my-form&#x5B;details]&#x5B;avatars]&#x5B;]&quot; /&gt;
Upload an avatar: &lt;input type=&quot;file&quot; name=&quot;my-form&#x5B;details]&#x5B;avatars]&#x5B;]&quot; /&gt;
</pre></div>


<p>Ecco cosa conterrà <code>$_FILES</code>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; gutter: false; title: ; notranslate">
array (
    'my-form' =&gt; array (
        'name' =&gt; array (
            'details' =&gt; array (
                'avatar' =&gt; array (
                    0 =&gt; 'my-avatar.png',
                    1 =&gt; 'my-avatar2.png',
                    2 =&gt; 'my-avatar3.png',
                ),
            ),
        ),
        'type' =&gt; array (
            'details' =&gt; array (
                'avatar' =&gt; array (
                    0 =&gt; 'image/png',
                    1 =&gt; 'image/png',
                    2 =&gt; 'image/png',
                ),
            ),
        ),
        'tmp_name' =&gt; array (
            'details' =&gt; array (
                'avatar' =&gt; array (
                    0 =&gt; 'phpmFLrzD',
                    1 =&gt; 'phpV2pBil',
                    2 =&gt; 'php8RUG8v',
                ),
            ),
        ),
        'error' =&gt; array (
            'details' =&gt; array (
                'avatar' =&gt; array (
                    0 =&gt; 0,
                    1 =&gt; 0,
                    2 =&gt; 0,
                ),
            ),
        ),
        'size' =&gt; array (
            'details' =&gt; array (
                'avatar' =&gt; array (
                    0 =&gt; 90996,
                    1 =&gt; 90996,
                    3 =&gt; 90996,
                ),
            ),
        ),
    ),
)
</pre></div>


<p>L&#8217;array sopra riportato corrisponderebbe alla seguente struttura restituita da <code>&lt;strong&gt;getUploadedFiles()&lt;/strong&gt;</code>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; gutter: false; title: ; notranslate">
array(
    'my-form' =&gt; array(
        'details' =&gt; array(
            'avatars' =&gt; array(
                0 =&gt; /* UploadedFileInterface instance */,
                1 =&gt; /* UploadedFileInterface instance */,
                2 =&gt; /* UploadedFileInterface instance */,
            ),
        ),
    ),
)
</pre></div>


<p>Per accedere all&#8217;elemento [1]:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; gutter: false; title: ; notranslate">
$request-&gt;getUploadedFiles()&#x5B;'my-form']&#x5B;'details']&#x5B;'avatars']&#x5B;1];
</pre></div>


<p>Seguendo il nostro esempio avremo:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; gutter: false; title: ; notranslate">
$file0 = $request-&gt;getUploadedFiles()&#x5B;'files']&#x5B;0];
$file1 = $request-&gt;getUploadedFiles()&#x5B;'files']&#x5B;1];

printf(
    &quot;Received the files %s and %s&quot;,
    $file0-&gt;getClientFilename(),
    $file1-&gt;getClientFilename()
);
</pre></div>


<p>Poiché le inforazioni sui file caricati, oltre che da <code>$_FILES</code>, possono derivare da altri elementi della richiesta,  è presente il metodo <code>&lt;strong&gt;withUploadedFiles()&lt;/strong&gt;</code> che consente di delegare la normalizzazione ad un altro processo.</p>



<p>Lo standard PSR-7 considera anche le implementazioni in ambienti non SAPI. Pertanto, <code>UploadedFileInterface</code> fornisce metodi per garantire che le operazioni funzionino indipendentemente dall&#8217;ambiente. In particolare:</p>



<ul><li><strong><code>moveTo($targetPath)</code></strong> viene fornito come alternativa sicura e consigliata per richiamare <code>move_uploaded_file()</code> sul file di caricamento temporaneo. Le implementazioni rileveranno il corretto funzionamento da utilizzare in base all&#8217;ambiente.</li><li><code>&lt;strong&gt;getStream()&lt;/strong&gt;</code> restituirà un&#8217;istanza <code>StreamInterface</code>. In ambienti non SAPI, una possibilità proposta è quella di eseguire il parsing dei file caricati nello stream <code>php://temp</code>.</li></ul>



<p>Ad esempio:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; gutter: false; title: ; notranslate">
// Move a file to an upload directory
$filename = sprintf(
    '%s.%s',
    create_uuid(),
    pathinfo($file0-&gt;getClientFilename(), PATHINFO_EXTENSION)
);
$file0-&gt;moveTo(DATA_DIR . '/' . $filename);

// Stream a file to Amazon S3.
// Assume $s3wrapper is a PHP stream that will write to S3, and that
// Psr7StreamWrapper is a class that will decorate a StreamInterface as a PHP
// StreamWrapper.
$stream = new Psr7StreamWrapper($file1-&gt;getStream());
stream_copy_to_stream($stream, $s3wrapper);
</pre></div>


<h2 class="wp-block-heading">PSR-7: Interfacce</h2>



<h3><a name="MessageInterface"></a>Psr\Http\Message\MessageInterface</h3>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
interface MessageInterface {
    /**
     * Recupera la versione del protocollo HTTP (Es: &quot;1.1&quot;, &quot;1.0&quot;)
     *
     * @return string HTTP protocol version.
     */
    public function getProtocolVersion();

    /**
     * Restituisce un'istanza con una specifica versione del protocollo HTTP
     *
     * @param string $version HTTP protocol version
     * @return static
     */
    public function withProtocolVersion($version);

    /**
     * Recupera tutti i valori di intestazione del messaggio
     *
     * @return string&#x5B;]&#x5B;] Returns an associative array of the message's headers.
     */
    public function getHeaders();

    /**
     * Verifica se esiste un'intestazione in base al nome senza distinzione tra maiuscole e minuscole.
     *
     * @param string $name Case-insensitive header field name.
     * @return bool
     */
    public function hasHeader($name);

    /**
     * Recupera un valore di intestazione del messaggio in base al nome senza distinzione tra maiuscole e minuscole.
     *
     * @param string $name Case-insensitive header field name.
     * @return string&#x5B;] An array of string values as provided for the given header.
     */
    public function getHeader($name);

    /**
     * Recupera una stringa separata da virgole dei valori per una singola intestazione.
     *
     * @param string $name Case-insensitive header field name.
     * @return string A string of values as provided for the given header concatenated together using a comma.
     */
    public function getHeaderLine($name);

    /**
     * Restituisce un'istanza sostituendo il valore dell'intestazione specificata.
     *
     * @param string $name Case-insensitive header field name.
     * @param string|string&#x5B;] $value Header value(s).
     * @return static
     * @throws \InvalidArgumentException for invalid header names or values.
     */
    public function withHeader($name, $value);

    /**
     * Restituisce un'istanza appendendo un valore al campo di intestazione specificato.
     *
     * @param string $name Case-insensitive header field name to add.
     * @param string|string&#x5B;] $value Header value(s).
     * @return static
     * @throws \InvalidArgumentException for invalid header names or values.
     */
    public function withAddedHeader($name, $value);

    /**
     * Restituisce un'istanza eliminando l'intestazione specificata.
     *
     * @param string $name Case-insensitive header field name to remove.
     * @return static
     */
    public function withoutHeader($name);

    /**
     * Ottiene il corpo del messaggio.
     *
     * @return StreamInterface Returns the body as a stream.
     */
    public function getBody();

    /**
     * Restituisce un'istanza con il corpo del messaggio specificato.
     *   
     * @param StreamInterface $body Body.
     * @return static
     * @throws \InvalidArgumentException When the body is not valid.
     */
    public function withBody(StreamInterface $body);
}
</pre></div>


<p></p>
<p>L'articolo <a href="https://www.cesarebordi.it/psr-7-http-message-standard-php-request-response/">PSR-7 Http Message: standard php per Request e Response.</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.cesarebordi.it/psr-7-http-message-standard-php-request-response/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>PSR-3 Logger Interface: standard log per PHP</title>
		<link>https://www.cesarebordi.it/psr-3-logger-interface-standard-log-php/</link>
					<comments>https://www.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://www.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://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p><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"><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>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>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>La parola <strong>implementatore</strong> (<code>&lt;strong&gt;implementor&lt;/strong&gt;</code>) utilizzata nel testo dello <strong>standard PSR3</strong> rappresenta qualcuno che implementa la <code>&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>user)</code>.</p>



<p>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>La <code>&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 = 'emergency';
    const ALERT     = 'alert';
    const CRITICAL  = 'critical';
    const ERROR     = 'error';
    const WARNING   = 'warning';
    const NOTICE    = 'notice';
    const INFO      = 'info';
    const DEBUG     = 'debug';
}

</pre></div>


<p>Un <strong>nono metodo</strong> <em><code>&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>&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>Di seguito il codice dell&#8217;interfaccia <a href="#LoggerInterface"><code>&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'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>La gestione dell&#8217;eccezione di <code>&lt;em&gt;Psr\Log\InvalidArgumentException&lt;/em&gt;</code> estende la classe nativa di php <code>&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><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>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>I nomi dei <strong>placeholder DEVONO corrispondere alle chiavi del context array</strong>.</p>



<p>I nomi dei <strong>placeholder DEVONO essere delimitati fra due parentesi graffe singole</strong> <code>{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>A-Z</code>, <code>a-z</code>, <code>0-9</code>, underscore <code>_</code>, e punto <code>.</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'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, '__toString'))) {
            $replace&#x5B;'{' . $key . '}'] = $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('username' =&gt; 'bolivar');

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


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



<p>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>Se nei context data viene passato <strong>un oggetto di tipo <code>&lt;em&gt;Exception&lt;/em&gt;</code>, questo DEVE essere passato nella chiave <code>&#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>&#039;exception&#039;</code></strong> sia realmente <strong>un oggetto di tipo <code>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>La classe di esempio <code>&lt;em&gt;Psr\Log\AbstractLogger&lt;/em&gt;</code> facilita l&#8217;implementazione di <code>&lt;em&gt;LoggerInterface&lt;/em&gt;</code> estendendola e implementando il metodo <code>log</code> generico. Gli altri otto metodi richiamano il metodo <code>&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>Similmente ad <code>AbstractLogger</code> è possibile creare un trait <code>&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>Veniamo ora al &#8220;piuttosto che niente&#8221;! <code>&lt;em&gt;Psr\Log\NullLogger&lt;/em&gt;</code> implementa  <code>&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">
&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><code>&lt;em&gt;Psr\Log\LoggerAwareInterface&lt;/em&gt;</code> contiene solo un metodo <code>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">
&lt;?php

namespace Psr\Log;

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


<p>Il trait <code>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>$this-&gt;logger</code>.</p>



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



<p>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://www.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://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.cesarebordi.it/psr-3-logger-interface-standard-log-php/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>PSR-1: regole per la scrittura di codice PHP</title>
		<link>https://www.cesarebordi.it/psr-1-regole-scrittura-codice-php/</link>
					<comments>https://www.cesarebordi.it/psr-1-regole-scrittura-codice-php/#respond</comments>
		
		<dc:creator><![CDATA[cesarebordi]]></dc:creator>
		<pubDate>Mon, 15 Jun 2020 10:08:11 +0000</pubDate>
				<category><![CDATA[Articoli]]></category>
		<category><![CDATA[Lezioni]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[guida]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php-fig]]></category>
		<category><![CDATA[phpfig]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[programmazione ad oggetti]]></category>
		<category><![CDATA[psr]]></category>
		<category><![CDATA[psr-1]]></category>
		<category><![CDATA[psr1]]></category>
		<category><![CDATA[standard]]></category>
		<guid isPermaLink="false">https://www.cesarebordi.it/?p=1170</guid>

					<description><![CDATA[<p>PSR-1 è lo standard promosso da PHP-FIG per definire delle regole per la scrittura di codice PHP così da facilitarne la lettura e la comprensione.</p>
<p>L'articolo <a href="https://www.cesarebordi.it/psr-1-regole-scrittura-codice-php/">PSR-1: regole per la scrittura di codice PHP</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p><strong>PSR-1</strong> è lo standard promosso da <strong><a rel="noreferrer noopener" href="https://www.php-fig.org/" target="_blank">PHP-FIG</a></strong> (<strong>PHP Framework Interop Group</strong>) che vuole definire le <strong>regole per la scrittura di codice PHP</strong> così da <strong>facilitare la lettura e la comprensione del codice</strong> da parte della community degli sviluppatori.</p>



<p>Prima di procedere con la lettura della lezione sullo <strong>standard PSR1</strong> consiglio di leggere le <a href="#note">note</a> in fondo alla pagina. Inoltre, nella sezione &#8220;<a href="https://www.cesarebordi.it/category/articoli/lezioni/">Lezioni</a>&#8220;, è possibile trovare altro materiale sugli standard <strong>PHPFIG</strong>.</p>



<h2 class="wp-block-heading">PSR-1: in breve</h2>



<ul><li>I <strong>file PHP DEVONO usare solo i tag <code>&lt;?php</code> e <code>&lt;?=</code></strong>,</li><li><strong>DEVONO usare solo la codifica UTF-8</strong> priva di BOM,</li><li><strong>DOVREBBERO dichiarare classi, funzioni, costanti</strong>, &#8230;<strong> OPPURE DOVREBBERO eseguire altri tipi di azioni logiche</strong> come generare output, modificare parametri di configurazione del php.ini, includere file &#8230; ma NON DOVREBBERO fare entrambe le cose.</li><li>I <strong>Namespaces e i Class Names DEVONO seguire lo standard per “autoloading” PSR-4</strong>: una sola classe in un solo file, namespace di almeno un livello indicante il vendor-name.</li><li>I <strong>Class Names DEVONO essere dichiarati in <code>StudlyCaps</code></strong>.</li><li>Le <strong>costanti DEVONO essere dischiarate in maiuscolo utilizzando l&#8217;underscore come separatore</strong>.</li><li>I <strong>nomi dei metodi DEVONO essere dichiarati in <code>camelCase</code></strong>.</li></ul>



<h2 class="wp-block-heading">PSR-1: files</h2>



<h3 class="wp-block-heading">PHP Tags</h3>



<p>Il codice PHP deve essere dichiarato attraverso i tag <code>&lt;?php ?&gt;</code> oppure gli short-echo <code>&lt;?= ?&gt;</code> tags. NON DEVE utilizzare altre varianti di tag dichiarativi (es: <code>&lt;? ?&gt;</code>).</p>



<h3 class="wp-block-heading">Codifica dei caratteri</h3>



<p>Il file <strong>PHP DEVE utilizzare solo la codifica UTF-8</strong> ed essere privo di <a href="https://it.wikipedia.org/wiki/Byte_Order_Mark" target="_blank" rel="noreferrer noopener">BOM</a>.</p>



<h3 class="wp-block-heading">Dichiarazioni ed effetti collaterali (side effects)</h3>



<p>Un file <strong>DOVREBBE dichiarare nuovi &#8220;simboli&#8221;</strong> (classi, funzioni, costanti, &#8230;) senza causare altri &#8220;effetti collaterali&#8221;<strong> OPPURE DOVREBBE eseguire una logica con effetti collaterali</strong>, <strong>MA NON DOVREBBE fare entrambe le cose</strong>.</p>



<p>Lo standard spiega che l&#8217;espressione &#8220;<strong>effetti collaterali</strong>&#8221; (side effects) indica l&#8217;esecuzione di una logica non direttamente correlata alla dichiarazione di classi, funzioni, costanti, ecc, ma correlata direttamente all&#8217;inclusione del file stesso. </p>



<p>Vengono poi fatti alcuni esempi di &#8220;effetti collaterali&#8221; a titolo esemplificativo: generazione di output, uso esplicito di <code>require</code> o <code>include</code>, connessione a servizi esterni, modifica di parametri del php.ini, generazione di errori o eccezioni, modifica di variabili statiche o globali, lettura/scrittura di file, &#8230;</p>



<p>Ecco un esempio di file non conforme allo standard con la coopresenza di dichiarazioni ed &#8220;effetti collaterali&#8221;.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
&lt;?php
// effetto collaterale: cambio ini setting
ini_set('error_reporting', E_ALL);

// effetto collaterale: carico un file
include &quot;file.php&quot;;

// effetto collaterale: genero output
echo &quot;&lt;html&gt;\n&quot;;

// dichiarazione una funzione
function foo() {
    // function body
}
</pre></div>


<p>Il seguente esempio mostra un file conforme allo standard contenete solo delle dichiarazioni:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
&lt;?php
// dichiarazione una funzione
function foo() {
    // function body
}

// la dichiarazione condizionale non è un effetto collaterale.
if (! function_exists('bar')) {
    function bar() {
        // function body
    }
}

</pre></div>


<h2 class="wp-block-heading">PSR-1: namespace e class names</h2>



<p>I <strong>namespaces</strong> ed i <strong>class names</strong> <strong>DEVONO essere conformi ad allo standard per l&#8217;autoloading</strong> <a rel="noreferrer noopener" href="https://www.php-fig.org/psr/psr-4/" target="_blank">PSR-4</a>.</p>



<p>Ciò significa che <strong>ogni classe DEVE essere dichiarata in un file dedicato</strong> e <strong>DEVE trovarsi in un Namespace di almeno un livello indicante il vendor-name</strong>, in pratica l&#8217;indicazione dello sviluppatore.</p>



<p>I <strong>class names DEVONO essere dichiarati in <code>StudlyCaps</code></strong>.</p>



<p>ll codice scritto da PHP 5.3 in avanti <strong>DEVE utilizzare namespaces formali</strong>.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
&lt;?php
// PHP 5.3 e successivi:
namespace Vendor\Model;

class Foo {
  // Class body
}
</pre></div>


<p>Il codice scritto per PHP 5.2 e versioni precedenti DOVREBBE usare la convenzione pseudo-namespacing con prefissi Vendor_ nei nomi delle classi.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
&lt;?php
// PHP 5.2.x e versioni precedenti:
class Vendor_Model_Foo {
  // Class body
}

</pre></div>


<h2 class="wp-block-heading">PSR-1: costanti di classe, proprietà e metodi</h2>



<p>Il termine “class” si usa qui in senso più ampio per riferirsi a tutte le classi, le interfacce ed i traits.</p>



<h3 class="wp-block-heading">Costanti</h3>



<p>Le <strong>costanti di classe DEVONO essere dischiarate in maiuscolo utilizzando l&#8217;underscore come separatore</strong>. Personalmente applico questa regola a tutte le costanti comprese quelle definite con define().</p>


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

class Foo {
    const VERSION = '1.0';
    const DATE_APPROVED = '2012-06-01';
}
</pre></div>


<h3 class="wp-block-heading">Proprietà</h3>



<p>Lo standard evita intenzionalmente di fornire consigli riguardanti l&#8217;uso dei nomi di prorpietà <code>$StudlyCaps</code>, <code>$camelCase</code>, or <code>$under_score</code> property names.</p>



<p>Qualunque sia la convenzione di denominazione utilizzata DOVREBBE essere applicato in modo coerente.</p>



<h3 class="wp-block-heading">Metodi</h3>



<p>I nomi dei <strong>metodi DEVONO essere dichiarati in <code>camelCase()</code></strong>.</p>



<hr class="wp-block-separator"/>



<h2 class="wp-block-heading">PSR1 nel lavoro di tutti i giorni</h2>



<p>Il nuovo <strong>framework CoreBox</strong> che stiamo sviluppando alla <a rel="noreferrer noopener" href="https://www.communicationbox.it" target="_blank">Communication Box </a>adererisce perfettamente allo <strong>standard PSR1</strong>. Questo facilita notevolmente lo sviluppo poiché ogni componente del team trova sempre una certa familiarità nel leggere il codice scritto dai colleghi.</p>



<hr class="wp-block-separator"/>



<h4 class="wp-block-heading" id="note"><strong>Note</strong></h4>



<p>Quando si legge un documento del PHP-FIG le parole DEVE (<strong><code>MUST</code></strong>), NON DEVE (<strong><code>MUST NOT</code></strong>), RICHIESTO (<strong><code>REQUIRED</code></strong>), POTRÀ (<strong><code>SHALL</code></strong>),  NON POTRÀ (<strong><code>SHALL NOT</code></strong>), DOVREBBE (<strong><code>SHOULD</code></strong>),  NON DOVREBBE (<strong><code>SHOULD NOT</code></strong>), RACCOMANDATO (<strong><code>RECCOMANDED</code></strong>), PUÒ (<strong><code>MAY</code></strong>) e OPZIONALE (<strong><code>OPTIONAL</code></strong>) vanno interpretati secondo quanto descritto nel documento <a rel="noreferrer noopener" href="http://www.ietf.org/rfc/rfc2119.txt" target="_blank">RFC 2119</a>.</p>



<p>Lo stile <strong></strong><strong><code>StudlyCaps</code></strong>, noto anche come PascalCase, impone che la prima lettera di ogni parola sia in maiuscolo.<strong> </strong>Una stringa in questo stile<strong> deve iniziare sempre con la lettera maiuscola</strong>.</p>



<p>Lo stile <strong></strong><strong><code>camelCase</code></strong>, proprio come in un cammello, impone che le gobbe siano solo in mezzo. Una stringa in questo stile <strong>deve iniziare sempre con la lettera minuscola</strong>.</p>
<p>L'articolo <a href="https://www.cesarebordi.it/psr-1-regole-scrittura-codice-php/">PSR-1: regole per la scrittura di codice PHP</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.cesarebordi.it/psr-1-regole-scrittura-codice-php/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Design Pattern Singleton in Php</title>
		<link>https://www.cesarebordi.it/design-pattern-singleton-php/</link>
					<comments>https://www.cesarebordi.it/design-pattern-singleton-php/#respond</comments>
		
		<dc:creator><![CDATA[cesarebordi]]></dc:creator>
		<pubDate>Thu, 21 May 2020 13:11:22 +0000</pubDate>
				<category><![CDATA[Lezioni]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[classi]]></category>
		<category><![CDATA[contro]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[esempio]]></category>
		<category><![CDATA[guida]]></category>
		<category><![CDATA[metodo]]></category>
		<category><![CDATA[oggetti]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[pro]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[programmazione ad oggetti]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[singleton]]></category>
		<guid isPermaLink="false">https://www.cesarebordi.it/?p=962</guid>

					<description><![CDATA[<p>Il singleton è il più conosciuto tra i design pattern creazionali. Vediamo come implementarlo in php e come usarlo nella programmazione ad oggetti (OOP).</p>
<p>L'articolo <a href="https://www.cesarebordi.it/design-pattern-singleton-php/">Design Pattern Singleton in Php</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Il <strong>singleton</strong> è tra i <a rel="noreferrer noopener" href="https://www.cesarebordi.it/design-pattern-gof-guida/" target="_blank">design pattern creazionali</a> più conosciuti e sul suo utilizzo nella <strong>programmazione ad oggetti</strong> (<strong>OOP</strong>) ci sono pareri contrastanti. Vediamo come <strong>implementarlo correttamente in PHP</strong> partendo dalla definizione data dalla <a rel="noreferrer noopener" href="https://it.wikipedia.org/wiki/Design_Patterns" target="_blank">Gang of Four</a> (GoF).</p>



<blockquote class="wp-block-quote">
<p>Il <strong>Singleton pattern</strong> assicura che una sola istanza di una classe esista, fornendo un punto di accesso globale a tale istanza.</p>
</blockquote>



<p>Il <strong>pattern Singleton</strong> impedisce la creazione di più istanze di una classe garantendo che ne esista solo una e fornisce un modo per accedere a quell&#8217;istanza unica da qualsiasi parte dell&#8217;applicazione.</p>



<p>Il singleton prevede tre elementi fondamentali:</p>



<ul>
<li><strong>Costruttore privato</strong>: impedisce la creazione di istanze della classe dal di fuori della classe stessa.</li>



<li><strong>Variabile statica privata</strong>: mantiene l&#8217;istanza unica della classe. Deve essere privata per evitare che altri oggetti accedano ad essa direttamente.</li>



<li><strong>Metodo statico di accesso all&#8217;istanza</strong>: restituisce l&#8217;istanza unica della classe. Se l&#8217;istanza non esiste ancora, il metodo crea l&#8217;istanza e la restituisce, altrimenti restituisce semplicemente l&#8217;istanza esistente.</li>
</ul>



<h2 class="wp-block-heading">Scenari di utilizzo</h2>



<p>Il <strong>pattern singleton</strong> può essere utilizzato quando un certo oggetto deve essere &#8220;unico&#8221; all&#8217;interno del nostro applicativo, per un ruolo di coordinamento o per ottimizzare le risorse. Ecco alcuni esempi concreti di utilizzo:</p>



<ul>
<li>Registro / Storage condiviso</li>



<li>Log / Debug</li>



<li>Connessione a DB persistente</li>
</ul>



<h2 class="wp-block-heading">Esempio di pattern Singleton in PHP</h2>



<p>Vediamo ora il codice di base per <strong>implementare</strong> questo pattern.</p>



<pre class="wp-block-prismatic-blocks"><code class="language-php">class MySingleton {

    /**
     * Istanza unica del singleton
     * @var object
     */
    private static object $instance;

    /**
     * Costruttore privato per prevenire che venga istanziato da codice esterno.
     */
    private function __construct() {
        echo &#039;Faccio qualcosa...&#039;;
    }

    /**
     * Metodo pubblico per l&#039;accesso all&#039;istanza unica di classe.
     * @return object|MySingleton
     */
    public static function getInstance() {
        if ( !isset(self::$instance) ) {
            self::$instance = new MySingleton();
        }
        return self::$instance;
    }
}</code></pre>



<p>Se proviamo ad istanziare due volte il singleton noteremo che il messaggio &#8220;Faccio qualcosa&#8230;&#8221; presente nel costruttore verrà mostrato una sola volta. poiché il sistema utilizzato per implementarlo garantisce l&#8217;unicità dell&#8217;istanza (oggetto).</p>



<pre class="wp-block-prismatic-blocks"><code class="language-"></code></pre>



<p>Per rendere il codice più riutilizzabile possiamo apportare una piccola modifica all&#8217;interno del metodo getIstance() in modo che il nome della classe istanziata con <em>new</em> sia valorizzato automaticamente. Sfruttiamo la <strong><a rel="noreferrer noopener" href="https://www.php.net/manual/en/language.constants.predefined.php" target="_blank">costante magica</a> __CLASS__</strong> che restituisce il nome della classe nella quale è richiamata.</p>



<pre class="wp-block-prismatic-blocks"><code class="language-php">if ( !isset(self::$instance) ) {
    $className = __CLASS__;
    self::$instance = new $className;
}</code></pre>



<h2 class="wp-block-heading">Vantaggi del design pattern singleton</h2>



<ul>
<li><strong>Garantisce una sola istanza:</strong> Il pattern Singleton garantisce che una sola istanza di una classe esista in un determinato momento, il che può essere utile in alcune situazioni, ad esempio per gestire le connessioni al database o le impostazioni globali dell&#8217;applicazione.</li>



<li><strong>Facile accesso globale:</strong> Il pattern Singleton fornisce un punto di accesso globale all&#8217;istanza unica, il che significa che possiamo accedere all&#8217;istanza ovunque e in qualsiasi momento senza dover preoccuparci di passare l&#8217;istanza esplicitamente a ogni parte dell&#8217;applicazione.</li>



<li><strong>Riduzione del consumo di memoria:</strong> Poiché una sola istanza esiste in un determinato momento, il pattern Singleton può aiutare a ridurre il consumo di memoria del sistema.</li>
</ul>



<h2 class="wp-block-heading">Svantaggi del design pattern singleton</h2>



<p>Alcuni puristi della programmazione ad oggetti (OOP) possono storcere il naso quando si parla di <strong>singleton</strong> definendolo un anti-pattern. Le principali critiche al singleton sono le seguenti:</p>



<p></p>



<ul>
<li><strong>Viola il Single Responsibility Principle</strong> (SRP) se crea delle dipendenze nei componenti che lo utilizzano. L&#8217;SRP vorrebbe infatti ogni componente assegnato ad una singola funzione o responsabilità.</li>



<li><strong></strong><strong>Difficile da testare</strong> poiché l&#8217;istanza unica esiste in tutta l&#8217;applicazione e non può essere facilmente sostituita con una mock o una versione di prova.</li>



<li><strong>Difficile da estendere</strong> poiché impone l&#8217;esistenza di una sola istanza di una classe in un determinato momento, può essere difficile estendere il pattern se si desidera introdurre più istanze della classe.</li>



<li><strong>Crea accoppiamento forte:</strong> poiché ogni parte dell&#8217;applicazione che utilizza il Singleton dipende dal suo stato globale.</li>



<li><strong>Viene utilizzato erroneamente per sostituire le variabili globali</strong> che, per definizione, non devono essere influenzate dall&#8217;applicativo.</li>
</ul>



<h2 class="wp-block-heading">Conclusioni</h2>



<p>Il singleton si può rivelare molto utile in specifiche situazioni, ma non bisogna abusarne così come non bisogna abusare delle implementazioni statiche nella programmazione ad oggetti. Può essere utile valutare anche altri tipi di soluzioni come la Dependency Injectiono il pattern Factory.</p>



<p>Per un panoramica generale consiglio di leggere l&#8217;<a href="https://www.cesarebordi.it/design-pattern-gof-guida/">articolo introduttivo sui <strong>design patterns</strong></a>.</p>
<p>L'articolo <a href="https://www.cesarebordi.it/design-pattern-singleton-php/">Design Pattern Singleton in Php</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.cesarebordi.it/design-pattern-singleton-php/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Design Pattern GoF &#8211; Guida</title>
		<link>https://www.cesarebordi.it/design-pattern-gof-guida-oop/</link>
					<comments>https://www.cesarebordi.it/design-pattern-gof-guida-oop/#respond</comments>
		
		<dc:creator><![CDATA[cesarebordi]]></dc:creator>
		<pubDate>Wed, 20 May 2020 16:42:00 +0000</pubDate>
				<category><![CDATA[Lezioni]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[classi]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[elementi per il riuso di software ad oggetti]]></category>
		<category><![CDATA[esempio]]></category>
		<category><![CDATA[gang of four]]></category>
		<category><![CDATA[gof]]></category>
		<category><![CDATA[guida]]></category>
		<category><![CDATA[metodo]]></category>
		<category><![CDATA[oggetti]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[pro]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[programmazione ad oggetti]]></category>
		<category><![CDATA[script]]></category>
		<guid isPermaLink="false">https://www.cesarebordi.it/?p=1010</guid>

					<description><![CDATA[<p>La conoscenza dei design pattern nello sviluppo di un software è fondamentale quando si passa dalla fase di analisi alla progettazione del design strutturale. </p>
<p>L'articolo <a href="https://www.cesarebordi.it/design-pattern-gof-guida-oop/">Design Pattern GoF &#8211; Guida</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>La conoscenza dei <strong>design pattern</strong> nello <strong>sviluppo di un software</strong> è fondamentale nel passaggio dalla fase di analisi alla progettazione del <strong>design strutturale</strong>. </p>



<p>Progettare software ad oggetti è difficile, ma lo è ancora di più renderne i suoi componenti riutilizzabili. La scomposizione dell&#8217;applicativo in <strong>oggetti</strong> deve tener conto di molteplici fattori: <strong>incapsulamento,</strong> <strong>granularità</strong>, <strong>dipendenza</strong>, <strong>performance</strong>, <strong>ridondanza</strong>, <strong>riusabilità</strong>, <strong>modularità</strong>, <strong>estendibilità nel tempo</strong>. </p>



<p>I<strong> design pattern vengono in nostro soccorso</strong> indicandoci soluzioni a problemi ricorrenti così da rendere il nostro codice riutilizzabile e mantenibile.</p>



<h2 class="wp-block-heading">La genesi</h2>



<p>Il concetto di <strong>design pattern</strong> è stato mutuato dall&#8217;<strong>ingegneria del software</strong> direttamente dall&#8217;<strong>architettura</strong>. Fu l&#8217;architetto austriaco Cristopher Alexander a formalizzare tale concetto nel 1977 all&#8217;interno del libro <em>Pattern Language: Towns, Buildings, Construction</em>.</p>



<blockquote class="wp-block-quote">
<p>Il pattern è una <em>soluzione architetturale che può risolvere problemi in contesti eterogenei</em>.</p>
</blockquote>



<p>La trasposizione del concetto di <strong>design pattern</strong> in ambito informatico è attribuita invece alla cosiddetta <strong><a rel="noreferrer noopener" href="https://it.wikipedia.org/wiki/Gang_of_Four_(scrittori)" target="_blank">Gang of Four</a></strong> (<strong>GoF</strong>) formata da Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides. Dopo quatro anni di confronto condensarono tutta la loro esperienza in un libro del 1994 che è diventato la &#8220;Bibbia della programmazione ad oggetti&#8221;: <a rel="noreferrer noopener" href="https://it.wikipedia.org/wiki/Design_Patterns" target="_blank"><strong><em>Design Patterns: elements of reusable object oriented software</em></strong>&#8220;</a> (<em><strong>Elementi per il riuso di software ad oggetti</strong></em>).</p>



<blockquote class="wp-block-quote">
<p>Il design pattern descrive un problema ricorrente e fornisce una soluzione che può essere riutilizzata infinite volte senza doverla applicare mai nello stesso identico modo</p>
</blockquote>



<h2 class="wp-block-heading">Design Pattern: classificazione</h2>



<p>La GoF cataloga i suoi 23 <strong>pattern</strong> suddividendoli in 3 macro categorie:</p>



<ul>
<li><strong>Pattern creazionali</strong>: soluzioni per creare oggetti.</li>



<li><strong>Pattern strutturali</strong>: soluzioni per la composizione strutturale di classi e oggetti.</li>



<li><strong>Pattern comportamentali</strong>: soluzioni per gestire le responsabilità delle classi e degli oggetti.</li>
</ul>



<p>Una seconda classificazione viene fatta in base al loro ambito applicativo:</p>



<ul>
<li><strong>Class pattern</strong>: soluzioni tramite classi e sottoclassi in relazioni statiche tra loro.</li>



<li><strong>Object Pattern</strong>: soluzioni dinamiche basate sugli oggetti.</li>
</ul>



<p>Infine ogni pattern viene descritto in base agli elementi che lo caratterizzano:</p>



<ul>
<li><strong>Nome</strong>/<strong>Alias</strong>: sintentizza l&#8217;essenza del pattern.</li>



<li><strong>Scopo</strong>: cosa fa il pattern.</li>



<li><strong>Motivazione</strong>: scenario del problema e soluzione offerta.</li>



<li><strong>Applicabilità</strong>: situazioni di esempio in cui si può usare il pattern.</li>



<li><strong>Struttura</strong>: rappresentazione grafica delle classi del pattern.</li>



<li><strong>Partecipanti</strong>: classi/oggetti interessati e relative responsabilità</li>



<li><strong>Collaborazioni</strong>: dei partecipanti per poter assumersi le responsabilità.</li>



<li><strong>Conseguenze</strong>: pro e contro del pattern.</li>



<li><strong>Implementazione</strong>: tecniche e consigli per implementare il pattern.</li>



<li><strong>Codice d&#8217;esempio</strong>: in C++ e SmallTalk.</li>



<li><strong>Utilizzi noti</strong>: esempi reali in sistemi esistenti.</li>



<li><strong>Correlazioni</strong>: legami con altri pattern e differenze.</li>
</ul>



<p>I 23 pattern definiti dal GoF possono essere quindi così schematizzati:</p>



<style>
#containerDesignPattern {border: 1px dashed #999 !important;}
#tableDesignPattern {width:100%; margin:0 !important; }
#tableDesignPattern * {text-align:center; color:#fff}
#tableDesignPattern td { border:8px solid #fff !important; margin:5px !important;}
.color-fff { background: #fff !important; }
.color-444 { background: #444 !important; }
.color-669 { background: #669 !important; }
.color-f30 { background: #f30 !important; }
.color-630 { background: #630 !important; }
</style>
<div id="containerDesignPattern">
<table id="tableDesignPattern">
  <tbody><tr>
    <td colspan="3" class="color-444"><h2 style="margin:0">GoF Design Patterns</h2></td>
  </tr>
  <tr>
    <td width="33%" class="color-669">CREAZIONALI<br />(creational)</td>
    <td width="33%" class="color-f30">STRUTTURALI<br />(structural)</td>
    <td width="33%" class="color-630">COMPORTAMENTALI<br />(behavioral)</td>
  </tr>
  <tr>
    <td colspan="3" class="color-444">Class Scope</td>
  </tr>
  <tr>
    <td class="color-669">Factory Method</td>
    <td class="color-f30">Adapter-class</td>
    <td class="color-630">Interpreter</td>
  </tr>
  <tr>
    <td class="color-fff"></td>
    <td class="color-fff"></td>
    <td class="color-630">Template Method</td>
  </tr>
  <tr>
    <td colspan="3" class="color-444">Object Scope</td>
  </tr>
  <tr>
    <td class="color-669">Abstract Factory</td>
    <td class="color-f30">Adapter-object</td>
    <td class="color-630">Chain of responsibility</td>
  </tr>
  <tr>
    <td class="color-669"><a href="https://www.cesarebordi.it/design-pattern-builder-php/" title="Design Pattern Builder">Builder [<i class="fas fa-graduation-cap"></i>]</a></td>
    <td class="color-f30">Bridge</td>
    <td class="color-630">Command</td>
  </tr>
  <tr>
    <td class="color-669">Prototype</td>
    <td class="color-f30">Composite</td>
    <td class="color-630">Iterator</td>
  </tr>
  <tr>
    <td class="color-669"><a href="https://www.cesarebordi.it/design-pattern-singleton-php/" title="Design Pattern Singleton">Singleton [<i class="fas fa-graduation-cap"></i>]</a></td>
    <td class="color-f30">Decorator</td>
    <td class="color-630">Mediator</td>
  </tr>
  <tr>
    <td class="color-fff">&nbsp;</td>
    <td class="color-f30">Facade</td>
    <td class="color-630">Memento</td>
  </tr>
  <tr>
    <td class="color-fff">&nbsp;</td>
    <td class="color-f30">Flyweight</td>
    <td class="color-630">Observer</td>
  </tr>
  <tr>
    <td class="color-fff">&nbsp;</td>
    <td class="color-f30">Proxy</td>
    <td class="color-630">State</td>
  </tr>
  <tr>
    <td class="color-fff">&nbsp;</td>
    <td>&nbsp;</td>
    <td class="color-630"><a href="https://www.cesarebordi.it/design-pattern-strategy-php/" title="Design Pattern Strategy">Strategy [<i class="fas fa-graduation-cap"></i>]</a></td>
  </tr>
  <tr>
    <td class="color-fff">&nbsp;</td>
    <td class="color-fff">&nbsp;</td>
    <td class="color-630">Visitor</td>
  </tr>
</tbody></table>
</div>



<h2 class="wp-block-heading">Design Pattern: il catalogo della GoF</h2>



<p>Riporto qui una sintesi del <strong>catalogo</strong> composto dai <strong>23 design pattern</strong> in modo da avere un&#8217;idea di massima del loro utilizzo.<br />Ricordo che con il termine &#8220;<strong><a rel="noreferrer noopener" href="https://it.wikipedia.org/wiki/Interfaccia_(informatica)#Interfaccia_nella_programmazione_orientata_agli_oggetti" target="_blank">interfaccia</a></strong>&#8221; si intende qui l&#8217;<strong>insieme delle richieste a cui un oggetto può rispondere</strong> cioè l&#8217;<strong>insieme delle proprietà e dei metodi pubblici di un oggetto.</strong> Attenzione quindi a non confondersi con le &#8220;interface&#8221; di Php!</p>



<ul>
<li><strong>Abstract Factory</strong>: fornisce un&#8217;interfaccia per la creazione di famiglie di oggetti correlati o dipendenti senza specificare o conoscere le classi concrete.</li>



<li><strong>Adapter</strong>: converte l&#8217;interfaccia di una classe in un&#8217;altra interfaccia richiesta dal client permettendo la collaborazione fra classi  tra loro incompatibili.</li>



<li><strong>Bridge</strong>: disaccoppia un&#8217;astrazione dalla sua implementazione in modo che le due possano variare indipendentemente.</li>



<li><strong><a href="https://www.cesarebordi.it/design-pattern-builder-php/">Builder</a></strong>: separa la costruzione di un oggetto complesso dalla sua rappresentazione così che lo stesso processo di creazione possa creare rappresentazioni diverse.</li>



<li><strong>Chain of Responsability</strong>: disaccoppia il mittente di una richiesta dal suo destinatario. Si ordinano gli oggetti destinatari e la richiesta viene passata di oggetto in oggetto finché non viene gestita.</li>



<li><strong>Command:</strong> incapsula una richiesta in un oggetto.</li>



<li><strong>Composite</strong>: raggruppa oggetti in strutture ad albero permettendo ai client di trattare oggetti singoli e raggruppamenti in modo uniforme.</li>



<li><strong>Decorator:</strong> aggiunge dinamicamente responsabilità ad un oggetto. E&#8217; un&#8217;aternativa flessibile all&#8217;ereditarietà.</li>



<li><strong>Facade</strong>: definisce un&#8217;interfaccia di più alto livello per facilitare l&#8217;utilizzo di un sottosistema più complesso.</li>



<li><strong>Factory Method</strong>: permette ad una classe di delegare la creazione di un oggetto alle sue sottoclassi.</li>



<li><strong>Flyweight</strong>: usa la condivisione per gestire numerosi oggetti a granularità fine.</li>



<li><strong>Interpreter</strong>: permette di implementare un proprio linguaggio con la sua grammatica ed il relativo interprete.</li>



<li><strong>Iterator</strong>: permette di accedere agli elementi di un contenitore sequenzialmente senza esporre la struttura sottostante.</li>



<li><strong>Mediator</strong>: favorisce un basso accoppiamento evitando che gli oggetti facciano riferimento l&#8217;un l&#8217;altro.</li>



<li><strong>Memento</strong>: esplicita lo stato interno di un oggetto così da poterlo riportare al suo stato originale.</li>



<li><strong>Observer</strong>: definisce una dipendenza uno-a-molti fra oggetti così che quando un oggetto cambia stato tutti gli oggetti dipendenti vengano notificati ed aggiornati.</li>



<li><strong>Prototype</strong>: specifica gli oggetti da creare utilizzando un&#8217;istanza prototipale.</li>



<li><strong>Proxy</strong>: fornisce un surrogato di un oggetto pper controllare l&#8217;accesso a quest&#8217;ultimo.</li>



<li><a href="https://www.cesarebordi.it/design-pattern-singleton-php/"><strong>Singleton</strong></a>: forza una classe ad avere una sola istanza e ne fornisce un accesso globale.</li>



<li><strong>State</strong>: permette ad un oggetto di modificare il proprio comportamento quando il suo stato interno cambia. Sembrerà che l&#8217;oggetto abbia cambiato la sua classe.</li>



<li><strong><a href="https://www.cesarebordi.it/design-pattern-strategy-php/">Strategy</a></strong>: definisce una famiglia di algoritmi, li incapsula e li rende interscambiabili tra di loro.</li>



<li><strong>Template Method</strong>: definisce lo scheletro principale dell&#8217;algoritmo in un metodo delegando alcuni passi alle sottoclassi.</li>



<li><strong>Visitor</strong>: permette di definire nuove operazioni senza cambiare le classi degli elementi su cui opera.</li>
</ul>



<h2 class="wp-block-heading">Riferimenti</h2>



<p><strong>Design Patterns: Elements of Reusable Object-Oriented Software</strong><br />Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides<br />Pearson Education</p>



<p><a href="https://designpatternsphp.readthedocs.io">https://designpatternsphp.readthedocs.io</a></p>



<p><a href="https://refactoring.guru/design-patterns">https://refactoring.guru/design-patterns</a></p>
<p>L'articolo <a href="https://www.cesarebordi.it/design-pattern-gof-guida-oop/">Design Pattern GoF &#8211; Guida</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.cesarebordi.it/design-pattern-gof-guida-oop/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Architettura REST per sviluppare Web Service</title>
		<link>https://www.cesarebordi.it/architettura-rest-per-sviluppare-web-service/</link>
					<comments>https://www.cesarebordi.it/architettura-rest-per-sviluppare-web-service/#respond</comments>
		
		<dc:creator><![CDATA[cesarebordi]]></dc:creator>
		<pubDate>Wed, 22 Apr 2020 17:55:01 +0000</pubDate>
				<category><![CDATA[Articoli]]></category>
		<category><![CDATA[Categorie]]></category>
		<category><![CDATA[Lezioni]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[TechNerd]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[architettura]]></category>
		<category><![CDATA[client]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[lezioni]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[restfull]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[web service]]></category>
		<category><![CDATA[webservice]]></category>
		<guid isPermaLink="false">https://www.cesarebordi.it/?p=833</guid>

					<description><![CDATA[<p>L'architettura REST è oggi una delle più utilizzate nell'ambito dei Web Service. Ci si trova spesso a dover implementare api RESTful ed è importante avere una precisa conoscenza di questo modello di progettazione.</p>
<p>L'articolo <a href="https://www.cesarebordi.it/architettura-rest-per-sviluppare-web-service/">Architettura REST per sviluppare Web Service</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>L&#8217;<strong>architettura REST</strong> è oggi una delle più utilizzate nell&#8217;ambito dei <strong>Web Service</strong>. Ci si trova spesso a dover <strong>implementare api RESTful</strong> ed è importante avere una precisa conoscenza di questo modello di progettazione.</p>



<h2 class="wp-block-heading">Architettura REST: cos&#8217;è?</h2>



<blockquote class="wp-block-quote"><p>Additional constraints can then be applied to form a new architectural style that better reflects the desired properties of a modern Web architecture.</p></blockquote>



<p><strong>REST</strong> vede la luce dieci anni dopo la nascita del <strong>World Wide Web</strong>, piattaforma per la condivisione di documenti distribuiti su server connessi tra loro. L’acronimo REST (<strong><span style="text-decoration: underline;">RE</span>presentational <span style="text-decoration: underline;">S</span>tate <span style="text-decoration: underline;">T</span>ransfer</strong>) viene introdotto nel 2000 nella tesi &#8220;<em><a rel="noreferrer noopener" href="https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm" target="_blank">Architectural Styles and the Design of Network-based Software Architectures</a></em>&#8221; di <a href="https://it.wikipedia.org/wiki/Roy_Fielding">Roy Fielding</a> definendo così uno&nbsp;<strong>stile architetturale</strong> basato sul Web che fissa un <strong>insieme di principi</strong> per la progettazione di un <a rel="noreferrer noopener" href="https://it.wikipedia.org/wiki/Sistema_distribuito" target="_blank">sistema hypermedia distribuito</a>.</p>



<p><strong>REST</strong> è quindi un modello di progettazione e non va confuso con un protocollo (non definisce messaggi) nè con una specifica (non definisce uno standard), ma opera ad un livello di astrazione superiore.<br />Non è quindi del tutto corretto confrontarlo con il <strong>protocollo <a rel="noreferrer noopener" href="https://it.wikipedia.org/wiki/SOAP" target="_blank">SOAP</a></strong> anche se entrambi sono oggi ampiamente usati nello <strong>sviluppo dei  Web Service</strong>.</p>



<p>In estrema sintesi:</p>



<blockquote class="wp-block-quote"><p>REST detta le regole per creare una piattaforma per l’elaborazione distribuita dei dati sfruttando l&#8217;architettura Web già dotata di tutto ciò che occorre: da una parte un&#8217;infrastruttura basata su protocolli ben definiti (<a rel="noreferrer noopener" href="https://it.wikipedia.org/wiki/Hypertext_Transfer_Protocol" target="_blank">HTTP</a> in primis) dall&#8217;altra le informazioni viste come risorse mappate univocamente (<a rel="noreferrer noopener" href="https://it.wikipedia.org/wiki/Uniform_Resource_Identifier" target="_blank">URI</a>).</p></blockquote>



<h2 class="wp-block-heading">I principi dell&#8217;architettura REST</h2>



<h3 class="wp-block-heading">Iniziare con un approccio &#8220;Null Style&#8221;</h3>



<p>Il &#8220;<strong>Null Style</strong>&#8221; è il punto di partenza: un sistema in cui non ci sono confini distinti tra i componenti (risorse) che andranno connessi. I seguenti <strong>principi dell&#8217;architettura REST</strong> rappresentano i <strong>vincoli</strong> per standardizzare l&#8217;accesso alle risorse distribuite in questo scenario.</p>



<h3 class="wp-block-heading">Client-Server </h3>



<p>L&#8217;<strong>architettura REST</strong> applica il paradigma <strong>SoC</strong> (<strong><span style="text-decoration: underline;">S</span>eparation <span style="text-decoration: underline;">o</span>f <span style="text-decoration: underline;">C</span>oncerns</strong>),  <em>&#8220;separazione dei compiti</em>“, al sistema di funzionamento Client-Server (<strong>Richiesta-Risposta</strong>). Il <strong>vincolo Client-Server</strong> favorisce un&#8217;architettura distribuita in cui lo sviluppo applicativo lato client è indipendente da quello lato server. Questo spiega anche perché REST non si preoccupa dei linguaggi e dei metodi di sviluppo.</p>



<h3 class="wp-block-heading">Stateless</h3>



<p>La comunicazione tra <strong>utente del servizio</strong> (<strong>client</strong>) ed il <strong>servizio</strong> (<strong>server</strong>) deve essere <strong>priva di stato</strong>: ogni richiesta del client deve contenere tutte le informazioni necessarie al server per comprendere la richiesta e non deve sfruttare informazioni di sessione memorizzate sul server. E&#8217; il client a gestire la sessione e, se necessario, dovrà ricevere opportune informazioni nella risposta del server.<br />Il <strong>vincolo stateless</strong> ha benefici sul monitoraggio delle richieste, sull&#8217;<strong>affidabilità</strong> e sulla <strong>scalabilità</strong>: non dovendo mantenere dati in sessione sarà più facile scalare orizzontalmente il servizio creando istanze parallele poste dietro ad un load balancer.</p>



<h3 class="wp-block-heading">Cache</h3>



<p>Nell&#8217;<strong>architettura REST</strong> il <strong>vincolo di Cache</strong> impone che le risposte siano etichettate come memorizzabili nella cache o meno. L&#8217;utilizzo della cache da parte di client, server o componenti middleware consente di ridurre le interazioni con la rete a tutto vantaggio delle performance.</p>



<h3 class="wp-block-heading">Uniform Interface</h3>



<p>L&#8217;<strong>architettura REST</strong> impone un <strong>vincolo di uniformità dell&#8217;interfaccia di accesso ai dati</strong> gestiti dal servizio, svincolandolo dalla specifica implementazione sottostante. Questo deve avvenire attraverso ulteriori sotto-vincoli.</p>



<h4 class="wp-block-heading"><span class="has-inline-color has-medium-gray-color">Identificazione delle risorse</span></h4>



<p>In REST ogni informazione è una<strong> risorsa</strong>, vista come qualsiasi cosa possa essere nominata: un documento, un&#8217;immagine, il meteo di oggi, &#8230;<br />Una risorsa può essere mutabile (l&#8217;ultima revisione di un documento) o immutabile nel tempo (la specifica revisione di un documento), l&#8217;unica cosa che deve essere statica è la semantica della sua mappatura, per questo motivo viene data una grande importanza all&#8217;<strong>identificazione univoca di una risorsa</strong> (<strong><a rel="noreferrer noopener" href="https://it.wikipedia.org/wiki/Uniform_Resource_Identifier" target="_blank">URI</a></strong>) e alla necessità di mantenerla nel tempo.<br />Tale sotto-vincolo sottolinea lo scopo organizzativo proprio dei nomi di domino Internet.</p>



<h4 class="wp-block-heading"><span class="has-inline-color has-medium-gray-color">Rappresentazione delle risorse</span></h4>



<p>Una risorsa può essere rappresentata in molti modi diversi (HTML, XML, JSON, SVG, JPG, &#8230;) attraverso <strong>dati</strong>, <strong>metadati</strong> descrittivi ed eventuali &#8220;<strong>control data</strong>&#8220;. I dati di controllo possono definire lo scopo di un messaggio di richiesta o risposta, il suo comportamento o stato. Ad esempio possono specificare come gestire la cache di una riposta o la necessità di creare una risorsa sulla base dei dati e delle caratteristiche presenti nella richiesta.<br /></p>



<h4 class="wp-block-heading"><span class="has-inline-color has-medium-gray-color">Collegamenti tra risorse</span></h4>



<p>L&#8217;architettura <strong>REST</strong> è pensata per <strong>connettere risorse tramite collegamenti ipertestuali</strong>. Questo principio è anche noto come <strong>HATEOAS</strong> (Hypermedia As The Engine Of Application State). Un Client deve quindi apprendere dalla rappresentazione di un risorsa fornita dal server (risposta) l&#8217;eventuale relazione con ulteriori risorse.<br />Ad esempio, richiedendo una fattura, la risposta dovrebbe contenere anche il link alla relativa anagrafica cliente.</p>



<h3 class="wp-block-heading">Layered System</h3>



<p>Un&#8217;architettura REST prevede più livelli architettonici, indipendenti l&#8217;uno dall&#8217;altro, frapposti fra client e server.<br />Gli strati intermedi possono avere scopi specifici durate il transito dei dati come ad esempio la sicurezza, il caching o il balancing.<br />I livelli potranno essere modificati in base all&#8217;evolversi dello scenario.</p>



<h3 class="wp-block-heading">Code-On-Demand</h3>



<p>L&#8217;ultimo <strong>vincolo di code-on-demand</strong> è facoltativo e consente ad un&#8217;implementazione REST di estendere le funzionalità del client scaricando ed eseguendo il codice sotto forma di applet o script. Ciò appare oggi abbastanza scontato e potrebbe rendere questo vincolo facoltativo quasi paradossale, ma non lo era nel 2000 quando i contenuti Web erano per lo più pagine statiche renderizzate dal browser.</p>



<h2 class="wp-block-heading">Differenza tra architettura REST ed servizio RESTful</h2>



<p>Eroneamente usati come sinonimi, <strong>REST</strong> è il nome dello “stile architetturale” mentre <strong>RESTful</strong> viene utilizzato per qualificare un Web Service che rispetta i vincoli dell&#8217;architettura REST.</p>



<h2 class="wp-block-heading">Architettura REST: i contro</h2>



<ul><li>L&#8217;architettura REST si può applicare solo in ambito Web a differenza del protocollo SOAP.</li><li>A causa del vincolo stateless c&#8217;è la possibilità di un aumento dei dati di ambiente restituiti ripetutamente in una serire di richieste (overhead per interazione). Il vincolo di Cache cerca di compensare questo aspetto.</li><li>A causa del vincolo stateless, spostando il controllo sul client si riduce il controllo da parte del server sul comportamento coerente dell&#8217;applicazione.</li></ul>
<p>L'articolo <a href="https://www.cesarebordi.it/architettura-rest-per-sviluppare-web-service/">Architettura REST per sviluppare Web Service</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.cesarebordi.it/architettura-rest-per-sviluppare-web-service/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Php Namespaces</title>
		<link>https://www.cesarebordi.it/php-namespaces/</link>
					<comments>https://www.cesarebordi.it/php-namespaces/#comments</comments>
		
		<dc:creator><![CDATA[cesarebordi]]></dc:creator>
		<pubDate>Thu, 16 Apr 2020 13:35:24 +0000</pubDate>
				<category><![CDATA[Articoli]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[classi]]></category>
		<category><![CDATA[codice]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[constant]]></category>
		<category><![CDATA[costanti]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[esempi]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[funzioni]]></category>
		<category><![CDATA[guida]]></category>
		<category><![CDATA[interfacce]]></category>
		<category><![CDATA[interface]]></category>
		<category><![CDATA[namespaces]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programmatore]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[programmazione ad oggetti]]></category>
		<category><![CDATA[web developer]]></category>
		<guid isPermaLink="false">https://www.cesarebordi.it/?p=572</guid>

					<description><![CDATA[<p>I namespaces in PHP rappresentano un'innovazione ed hanno legami stretti con lo standard PSR-4 e l'autoloading delle classi.</p>
<p>L'articolo <a href="https://www.cesarebordi.it/php-namespaces/">Php Namespaces</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<p class="has-text-align-left has-text-align-justify">L&#8217;introduzione dei <strong>namespaces </strong>in <strong>PHP</strong> rappresenta un&#8217;innovazione nel <strong>linguaggio </strong>ed ha legami stretti con lo <strong><a rel="noreferrer noopener" aria-label=" (apre in una nuova scheda)" href="https://www.php-fig.org/psr/psr-4/" target="_blank">standard PSR-4</a></strong> e l&#8217;<strong>autoloading delle classi</strong>.  A livello teorico l&#8217;argomento può sembrare semplice, ma nell&#8217;<strong>implementazione del codice</strong> non è così immediato.</p>
</div></div>



<h2 class="wp-block-heading">Cosa sono i namespaces in php?</h2>



<blockquote class="wp-block-quote"><p>What are namespaces? In the broadest definition namespaces are a way of encapsulating items.</p></blockquote>



<p>I <strong><a href="https://www.php.net/manual/en/language.namespaces.rationale.php">namespaces</a></strong>, introdotti in <strong>PHP 5.3</strong> e migliorati in<strong> PHP 7</strong>, permettono di <strong>raggruppare </strong><span style="text-decoration: underline;"><strong>classi</strong></span>, <span style="text-decoration: underline;"><strong>interfacce</strong></span>, <span style="text-decoration: underline;"><strong>funzioni</strong></span> e<strong> </strong><span style="text-decoration: underline;"><strong>costanti</strong></span> per evitare ambiguità di denominazione. In questo modo potremo far coesistere classi <span style="text-decoration: underline;">con lo stesso nome</span> &#8220;incapsulate&#8221; in namespace differenti esattamente come avviene per file con lo stesso nome posti in cartelle diverse del filesystem.  La possibilità di creare una gerarchizzazione (<strong>sub-namespace</strong>) fornisce una chiara indicazione sull&#8217;organizzazione delle risorse del nostro applicativo.  Ad esempio, assegnando i namespaces <em><strong><code>Framework\Core\Main</code></strong></em> ad un file contenente una classe e <em><strong><code>Framework\Core\Main\Libs</code></strong></em> ad un altro contenente un&#8217;altra classe con il medesimo nome, è facilmente intuibile come la prima si riferisca alle funzionalità di base del nostro ipotetico framework e l&#8217;altra sia presente in una libreria secondaria.</p>



<p>Pur essendo forte l&#8217;analaogia con il filesystem <strong>non sussite alcuna relazione diretta fra un namespace ed il percorso dei file .php</strong>. E&#8217; però intuitivo utilizzare questa analogia per creare vincoli convenzionali e sfruttarli nella pratica dell&#8217;autoloading la cui implementazione più diffusa è sintetizzata nello standard <a rel="noreferrer noopener" aria-label=" (apre in una nuova scheda)" href="https://www.php-fig.org/psr/psr-4/" target="_blank">PSR-4</a> che approfondirò in un altro articolo.</p>



<h2 class="wp-block-heading">Namespaces: vantaggi di utilizzo</h2>



<ul><li><strong>Risolvono il problema di omonimia</strong> di <span style="text-decoration: underline;">classi, interfacce, funzioni e costanti</span> tra il codice scritto dallo sviluppatore, quello integrato in librerire di terze parti e quello nativo di Php.</li><li><strong>Facilitano lo sviluppo di codice ordinato</strong>, organizzato ed &#8220;eloquente&#8221;.</li><li><strong>Migliorano la leggibilità e la scrittura del codice</strong> permettendo di utilizzare degli <strong>alias </strong>nel momento in cui la precisa ed inevitabile lunghezza del namespace non fosse necessaria.</li></ul>



<h2 class="wp-block-heading">Namespaces: dichiarazione</h2>



<p>Compresi i vantaggi  del loro utilizzo vediamo come utilizzare i namespaces iniziando dalla loro dichiarazione attraverso l&#8217;apposita <span style="text-decoration: underline;">keyword <code>&lt;strong&gt;namespace&lt;/strong&gt;</code></span>.<br />Uno script che faccia uso di namespaces deve dichiararlo all&#8217;inizio del listato fatta eccezione per i commenti ed eventuali istruzioni <em>declare</em>.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
&lt;?php
declare(encoding='UTF-8');

// Dichiaro il namespace...
namespace Framework\Core\Main;
</pre></div>


<h3 class="wp-block-heading">Attenzione!</h3>



<ul><li>I namespaces<strong> non possono contenere keywords</strong> del linguaggio php.<br /><strong><em><code>Framework\Core\&lt;s&gt;Class&lt;/s&gt;</code></em></strong></li><li>I namespaces <strong>non possono iniziare con un numero</strong>.<br /><em><strong><code>Framework\Core\&lt;s&gt;1Class&lt;/s&gt;</code></strong></em></li><li>E&#8217; possibile, ma altamente<strong> sconsigliato, dichiarare più namespaces nello stesso file</strong> utilizzando le parentesi graffe.<br /><code>&lt;?php&lt;br /&gt;&lt;em&gt;&lt;strong&gt;Framework\Core\Main&lt;/strong&gt;&lt;/em&gt; { // codice }&lt;br /&gt;&lt;em&gt;&lt;strong&gt;Framework\Core\Libs&lt;/strong&gt;&lt;/em&gt; { // codice }</code></li></ul>



<h2 class="wp-block-heading">Php Namespaces: dalla teoria alla pratica</h2>



<p>Immaginiamo di creare ed includere due file php contenenti la dichiarazione di una classe denominata nello stesso modo (Es: <code>MyClass</code>). Una volta in esecuzione otterremmo questo errore:<br /><code>&lt;strong&gt;Fatal error&lt;/strong&gt;:  Cannot declare class MyClass, because the name is already in use</code></p>



<p>Aggiungiamo ora ai due file una dichiarazione namespace&#8230;</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
&lt;?php // File 1: /Framework/Core/Main/MyClass.php

namespace Framework\Core\Main;

Class MyClass {
    public function __construct() {
        echo '&lt;p&gt;MAIN: MyClass ready!&lt;/p&gt;';
    }
}
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: php; title: ; notranslate">
&lt;?php // File 2: /Framework/Core/Main/Libs/MyClass.php

namespace Framework\Core\Main\Libs;

Class MyClass {
    public function __construct() {
        echo '&lt;p&gt;LIBS: MyClass ready!&lt;/p&gt;';
    }
}
</pre></div>


<p>Creiamo ora il file principale ex01.php che li includerà e tenterà di creare un oggetto.</p>


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

// Includo i file
require_once('Framework/Core/Main/MyClass.php');
require_once('Framework/Core/Main/Libs/MyClass.php');

// Creo l'oggetto
$objOne = New MyClass();
</pre></div>


<p>Mandandolo in esecuzione ci troveremo davanti ancora un errore&#8230;<br /><code>&lt;strong&gt;Fatal error&lt;/strong&gt;:  Uncaught Error: Class &#039;MyClass&#039; not found in...</code></p>



<p>Questo si verifica poichè le nostre due classi &#8220;MyClass&#8221; sono assegnate ai rispettivi namespaces, mentre il nostro file principale non ha alcun namespace specificato e si riferisce quindi a quello globale in cui la classe MyClass() non è definita.</p>



<h2 class="wp-block-heading">Namespaces: tipi di riferimento</h2>



<p>Sappiamo definire i namespaces, ma per richiamarli correttamente dobbiamo conoscere quali sono i <strong>tipi di riferimento</strong> che possiamo utilizzare e che nuovamente hanno una forte analogia con i percorsi dei filesystem:</p>



<ul><li><strong>Unqualified name</strong> (nomi non qualificati): si riferiscono solo al namespace corrente.  È come cercare un fille nella cartella in cui ci si trova.<br /><code>MyClass()</code></li><li><strong>Qualified name</strong> (nomi qualificati): paragonabile al percorso relativo di un file.<br /><code>Main\Libs\MyClass()</code></li><li><strong>Fully-qualified name</strong> (nomi completamente  qualificati): inizia sempre con un backslash iniziale ed è paragonabile ad un percorso assoluto.  È il modo  più sicuro anche se più verboso. <br /><code>\Framework\Core\Main\Libs\MyClass()</code></li></ul>



<p><strong>Unqualified name</strong> &#8211; Nel file principale (ex02.php) dichiariamo lo stesso namespace di uno dei due file contenenti la dichiarazione di MyClass() che vorremmo richiare, ad esempio Libs: <code>Framework\Core\Main\Libs</code>. Ecco finalmente il primo risultato positivo!</p>


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

// Dichiaro il namespace
namespace Framework\Core\Main\Libs;

// Includo i file
require_once('Framework/Core/Main/MyClass.php');
require_once('Framework/Core/Main/Libs/MyClass.php');

// UNQUALIFIED NAME...
$objOne = New MyClass();
</pre></div>


<p><strong>Qualified name</strong> &#8211; Nel file principale (ex03.php) dichiariamo un namespace più generico <code>Framework\Core</code> ed utilizzamo nomi qualificati per riferirci ad entrambe le nostre classi ed ottenere i relativi oggetti.</p>


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

// Dichiaro il namespace
namespace Framework\Core;

require_once('Framework/Core/Main/MyClass.php');
require_once('Framework/Core/Main/Libs/MyClass.php');

// QUALIFIED NAME...
$objOneMain = New Main\MyClass();
$objOneLib = New Main\Libs\MyClass();
</pre></div>


<p><strong>Nota</strong>: una volta dichiarato un namespace, per riferirsi al contesto globale è necessario anteporre il backslash.</p>



<p><strong>Fully-qualified name</strong> &#8211;  Nel file principale (ex04.php) omettiamo il namespace, ma utilizziamo un nome completamente qualificato per riferirci alle due classi.</p>


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

// Includo i file
require_once('Framework/Core/Main/MyClass.php');
require_once('Framework/Core/Main/Libs/MyClass.php');

// FULLY-QUALIFIED NAME...
$objOneMain = New \Framework\Core\Main\MyClass();
$objOneLib = New \Framework\Core\Main\Libs\MyClass();
</pre></div>


<h2 class="wp-block-heading">Php Namespaces: importazione e aliasing tramite l&#8217;operatore &#8220;use&#8221;</h2>



<p>Una caratteristica importante dei namespaces è la possibilità di essere importati e di creare degli alias per renderne più pratico l&#8217;utilizzo vista la loro &#8220;eloquenza&#8221;. Queste funzioni trovano un parallelismo nella capictà dei filesystem di creare link simbolici a file o cartelle.<br />A tale scopo Php mette a disposizione la <span style="text-decoration: underline;">keyword <code>&lt;strong&gt;use&lt;/strong&gt;</code></span> con la quale è possibile eseguire i seguenti tipi di seguenti tipi di importazione/aliasing:</p>



<ul><li>nomi di classi o interfacce (<code>use Name\Space\ClassName</code>),  </li><li>nomi di classi o interfacce globali (<code>use DateTime</code>)</li><li>namespaces (use <code>Name\Space\For\...</code>)</li><li>nomi di funzioni (<code>use&nbsp;function Name\Space\FunctionName</code>)</li><li>nomi di costanti (<code>use&nbsp;const&nbsp;Name\Space\CONSTANT</code>).</li></ul>



<p>E&#8217; possibile importare anche più elementi nello stesso file purché non si generino delle ambiguità, in tal caso si potrà ricorrere agli alias. </p>



<p>Applichiamo <code>use</code> al nostro scenario di esempio (ex05.php) per importare i namespaces comuni alla due classi e sintetizzarli in &#8220;Main&#8221;.</p>


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

use Framework\Core\Main as Main;

// Includo i file
require_once('Framework/Core/Main/MyClass.php');
require_once('Framework/Core/Main/Libs/MyClass.php');

// QUALIFIED NAME...
$objOneMain = New Main\MyClass();
$objOneLib = New Main\Libs\MyClass();
</pre></div>


<p>Nell&#8217;esempio seguente (ex06.php) utilizziamo <code>use</code> per superare l&#8217;ambiguita dei nomi delle classi e creare un alias dei namespaces.</p>


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

use Framework\Core\Main\MyClass as MainMy;
use Framework\Core\Main\Libs\MyClass as LibsMy;

// Includo i file
require_once('Framework/Core/Main/MyClass.php');
require_once('Framework/Core/Main/Libs/MyClass.php');

// UNQUALIFIED NAME...
$objOneMain = New MainMy();
$objOneLib = New LibsMy();
</pre></div>


<p>Direi sia tutto! Qui trovate i file di esempio visti nella lezione e se l&#8217;articolo è stato utile&#8230; condividilo!</p>



<div class="wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex">
<div class="wp-block-button"><a class="wp-block-button__link has-text-color has-white-color has-background has-black-background-color" href="https://www.cesarebordi.it/lessons/downloads/namespaces.zip" target="_blank" rel="noreferrer noopener">SCARICA I FILE DI ESEMPIO: namespaces.zip</a></div>
</div>
<p>L'articolo <a href="https://www.cesarebordi.it/php-namespaces/">Php Namespaces</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.cesarebordi.it/php-namespaces/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Conversione immagine: Imagemagick RGB to CMYK in PHP</title>
		<link>https://www.cesarebordi.it/imagemagick-rgb-to-cmyk-php/</link>
					<comments>https://www.cesarebordi.it/imagemagick-rgb-to-cmyk-php/#respond</comments>
		
		<dc:creator><![CDATA[cesarebordi]]></dc:creator>
		<pubDate>Mon, 04 Dec 2017 19:32:24 +0000</pubDate>
				<category><![CDATA[Articoli]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[imagemagick]]></category>
		<category><![CDATA[imagick]]></category>
		<category><![CDATA[immagini]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[web developer]]></category>
		<category><![CDATA[web project]]></category>
		<category><![CDATA[webserver]]></category>
		<guid isPermaLink="false">http://www.cesarebordi.it/?p=473</guid>

					<description><![CDATA[<p>Spero di poter aiutare i colleghi developer alle prese con la conversione attraverso Imagemagick RGB to CMYK. Scenario: dobbiamo convertire lato server un&#8217;immagine RGB in CMYK Problema: letta...</p>
<p>L'articolo <a href="https://www.cesarebordi.it/imagemagick-rgb-to-cmyk-php/">Conversione immagine: Imagemagick RGB to CMYK in PHP</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Spero di poter aiutare i colleghi developer alle prese con la conversione attraverso <strong>Imagemagick RGB to CMYK</strong>.<br />
<span id="more-473"></span></p>
<p><strong>Scenario</strong>: dobbiamo convertire lato server un&#8217;immagine<strong> RGB in CMYK</strong></p>
<p><strong>Problema</strong>: letta la scarna documentazione di <strong>Imagemagick</strong> sulla refernece di <strong>Php</strong> ci imbattiamo in un annoso problema: l&#8217;<strong>immagine ottenuta è in negativo</strong>!!!</p>
<p><strong>Soluzione</strong>: dopo aver letto post su post sui soliti siti senza riuscire a trovare una soluzione e grazie al supporto di Giacomarco, ecco svelato il mistero.</p>
<p>Se si deve convertire un&#8217;immagine occorre usare&nbsp;<strong>transformimagecolorspace</strong>, mentre se si sta generando un&#8217;immagine ex-novo allora si deve utilizzare <strong>transformimagecolorspace:</strong></p>
<pre class="brush: php; title: ; notranslate">$image-&amp;gt;transformimagecolorspace(Imagick::COLORSPACE_CMYK);</pre>
<p>Se invece si sta creando un&#8217;immagine ex-novo allora si deve utilizzare&nbsp;<strong>setImageColorSpace</strong></p>
<pre class="brush: php; title: ; notranslate">$image-&amp;gt;setImageColorSpace(Imagick::COLORSPACE_CMYK);</pre>
<p>Ecco un esempio:</p>
<pre class="brush: php; title: ; notranslate">
$image = new Imagick();
$image-&amp;gt;readImage(rgb.jpg);
$image-&amp;gt;transformimagecolorspace(Imagick::COLORSPACE_CMYK);
$image-&amp;gt;profileImage('icc', file_get_contents(/path/CoatedFOGRA27.icc'));
$image-&amp;gt;writeImage(cmyk.rgb);
</pre>
<p>Per gli amici in lingua inglese: <span lang="en"><strong>[SOLVED] imagemagick convert image RGB to CMYK</strong>!</span></p>
<p>L'articolo <a href="https://www.cesarebordi.it/imagemagick-rgb-to-cmyk-php/">Conversione immagine: Imagemagick RGB to CMYK in PHP</a> sembra essere il primo su <a href="https://www.cesarebordi.it">Cesare Bordi | Innovation Manager &amp; Back-end Developer</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.cesarebordi.it/imagemagick-rgb-to-cmyk-php/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
