Guide

Storage OnLine: Utilizzare API S3 con PHP per leggere i dati

Abbiamo già introdotto l'utilizzo delle S3 API in PHP; questa guida tratta dell'utilizzo della stessa libreria per leggere i dati dallo Storage OnLine, creando una sorta di file browser semplificato.

Struttura del file system

Le soluzioni di Storage OnLine, per poter garantire le performance e la sicurezza che li caratterizzano, hanno dovuto semplificare la struttura del file system, adottando i concetti di bucket/oggetti ed eliminando le struttura ricorsiva delle directory.

Il funzionamento è molto semplice: i bucket sono i contenitori di più alto livello e al loro interno vengono memorizzati gli oggetti, ognuno con un nome univoco (all'interno dello stesso bucket). Solitamente i bucket sono associati ad una singola applicazione o utente, per suddividere in modo netto lo spazio di storage. Affinchè si possa vedere una struttura ad albero come quella delle cartelle directory è l'utilizzo dei cosiddetti delimitatori, solitamente il carattere "/", all'interno del nome dell'oggetto.

Un file browser in PHP

Di seguito il codice PHP per leggere i contenuti del bucket sullo Storage OnLine. Nella cartella dello spazio web, creare due sotto-cartelle: conf e lib. In quest'ultima quindi copiare il file S3.php, ovvero la libreria PHP per accedere allo storage. In conf creiamo invece il file configuration.php:

<?php
require_once 'lib/S3.php';
define('s3AccessKey', 'USERNAME');
define('s3SecretKey', 'PASSWORD');
define('s3EndPoint', 'ACCESSO_S3');

$s3 = new S3(s3AccessKey, s3SecretKey);
$s3->setExceptions(true);
$s3->setEndpoint(s3EndPoint);
$s3->setSSL(true, false);
?>      

dove USERNAME, PASSWORD E ACCESSO_S3 sono i valori che vengono mostrati nella pagina di attivazione del protocollo S3 da pannello di controllo e che vengono forniti anche nella email che segue l'attivazione del servizio.

Creare, quindi, il file index.php nella root dello spazio web:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?php
try {
  require_once 'conf/configuration.php';
  $buckets = $s3->listBuckets();
}
catch(Exception $ex) {
  $errorMessage = "Si è verificato un errore (" . $ex->getCode() . "):\n" . $ex->getMessage();
  $errorMessage = nl2br(htmlspecialchars($errorMessage, ENT_NOQUOTES, 'UTF-8'));
}
?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>S3 API test</title>
  <link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<?php
if (isset($errorMessage)) {
?>
  <div class="errorMessage">
    <?php echo $errorMessage; ?>
  </div>
<?php
}
else {
?>
  <h3>Elenco bucket</h3>
  <ul>
<?php
    foreach($buckets as $bucket) {
      $url = "listObjects.php?bucketName=$bucket";
?>
      <li><?php echo '<a href="' . $url . '">' . $bucket . '</a>'; ?></li>
<?php
    }
?>
  </ul>
<?php
}
?>
</body>      

Questa pagina si collega all'account di storage ed effettua l'elenco dei bucket (solitamente uno), aggiungendo un link alla pagina listObjects.php, utilizzata per mostrare i contenuti del bucket. Ecco il sorgente della pagina:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?php
try {
  // configurazione
  require_once 'conf/configuration.php';
  // azioni
  $bucketName = $_REQUEST['bucketName'];
  $prefix = isset($_REQUEST['prefix']) ? $_REQUEST['prefix'] : '';
  $contents = $s3->getBucket($bucketName, $prefix);
}
catch(Exception $ex) {
  $errorMessage = "Si è verificato un errore (" . $ex->getCode() . "):\n" . $ex->getMessage();
  $errorMessage = nl2br(htmlspecialchars($errorMessage, ENT_NOQUOTES, 'UTF-8'));
}
?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>S3 API test</title>
  <link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<?php
if (isset($errorMessage)) {
?>
  <div class="errorMessage">
    <?php echo $errorMessage; ?>
  </div>
<?php
}
else {
?>

<h3>Elenco oggetti del bucket: 
<em><?php echo htmlspecialchars($bucketName, ENT_NOQUOTES, 'UTF-8');?></em></h3>
  
<p><a href="index.php">Elenco bucket</a></p>
  
<form method="post" action="listObjects.php">
<input name="bucketName" type="hidden" 
value="<?php echo htmlspecialchars($bucketName, ENT_NOQUOTES, 'UTF-8');?>"/>
<input name="prefix" value="<?php echo htmlspecialchars($prefix, ENT_NOQUOTES, 'UTF-8');?>" />
<button type="submit">Filtra</button>
</form>

<ul>
<?php
  foreach ($contents as $object) {
    $name = htmlspecialchars($object['name'], ENT_NOQUOTES, 'UTF-8');
    echo "<li>$name</li>";
  }
?>
</ul>
<?php
}
?>
</body>
	

Questa pagina ci permette anche di filtrare il nome degli oggetti, ecco un esempio, senza filtri:

e con il filtro "foto":

L'elenco degli oggetti è creato dalla chiamata al metodo getBucket().

Infine, salvare anche il file style.css nella stessa directory di index.php:

div.errorMessage {
  background: #ffffcc;
  border: 2px solid red;
  padding: 3px;
}    

Ora, un ultimo accorgimento molto importante per la sicurezza. Se si usa il web server Apache e le direttive .htaccess sono abilitate, salvare nelle cartella lib e conf un file .htaccess con questa riga:

deny from all
	

Questa operazione è molto importante, perchè impedisce che la configurazione (con relativa chiave segreta) sia leggibile da non autorizzati.

Risorse