<?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>webservice Archivi - Cesare Bordi | Innovation Manager &amp; Back-end Developer</title>
	<atom:link href="https://www.cesarebordi.it/tag/webservice/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.cesarebordi.it/tag/webservice/</link>
	<description>Innovare con soluzioni software efficaci e gioco di squadra</description>
	<lastBuildDate>Tue, 24 Nov 2020 07:48:42 +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>webservice Archivi - Cesare Bordi | Innovation Manager &amp; Back-end Developer</title>
	<link>https://www.cesarebordi.it/tag/webservice/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<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>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>
	</channel>
</rss>
