2. Server Side

In questo capitolo vedremo il codice Server Side in PHP 5, responsabile della gestione e della memorizzazione del file inviato tramite l'applicazione in ActionScript 3, che studieremo invece nei capitoli successivi.

Come già anticipato nei capitoli precedenti, le classi in questione le abbiamo già viste nella Guida a PHP 5, più esattamente nel capitolo Classi per l'upload di file.

Il codice della classe ErroreFile è rimasto invariato, mentre per la classe File ho definito un distruttore e ho effettuato qualche modifica al costruttore, ma prima di introdurre queste modifiche è necessaria una premessa.

La classe FileReference non ci consente di ricevere una risposta personalizzata dallo script PHP che si occuperà dell'archiviazione del file inviato, ma ci consente solo di gestire delle determinate eccezioni tramite i blocchi try e catch.

Questo fattore ci obbliga a interrogare un secondo script PHP una volta che il file è stato inviato,per verificarne l'effettiva archiviazione sul server.
Inoltre, nel caso in cui l'archiviazione non fosse andata a buon fine, ho ampliato la classe File come ho accennato prima, inserendo nel costruttore e nel distruttore del codice che creerà un file di log sul server, in modo da poter risalire con maggior precisione al motivo per cui il file non è stato accettato.

Per prima cosa vediamo il codice PHP della nuova classe UploadSettings, una collezione di costanti che ci consentirà di configurare rapidamente il nostro script :

UploadSettings.php
<?php

	final class UploadSettings
	{
		const NAME = "Filedata";
		const MAX_SIZE = 1024; // Espresso in KiloByte
		const FILE_PATH = "C:/Appserv/www/RealizzazioneSito/articoli/as3 files/upload/";

		const LOG_ME = true;
		const LOG_FILE = "upload.log";
	}

?>

Di default la classe ActionScript FileReference, invierà il file al server con il nome Filedata, accessibile quindi da PHP tramite l'array globale $_FILES["Filedata"].
Dal momento che è possibile assegnare un nome personalizzato al file, ho creato la costante NAME nella classe PHP UploadSettings, in modo da poter riconoscere immediatamente il file inviato.

Seguono altre costanti come MAX_SIZE che definisce la dimenzione massima in kilobyte che il file potrà avere.
FILE_PATH indica la cartella del server dove dovranno essere salvati i file inviati.
Infine le costanti LOG_ME e LOG_FILE indicano rispettivamente se lo script dovrà loggare le attività di upload, e il nome del file di log.

A questo punto non ci resta che dare un'occhiata alle modifiche effettuate alla classe File.
Oltre alle modifiche a costruttore e distruttore, ho definito una nuova costante che consentirà allo script di accettare anche file di tipo generico, rappresentando il tipo MIME corrispondente alla stringa "application/octet-stream".

File.php
<?php

	require_once("ErroreFile.php");
	require_once("UploadSettings.php");

	// MIME Types
	define("GIF", "image/gif");
	define("JPEG", "image/jpeg");
	define("PNG", "image/png");
	define("PSD", "image/psd");
	define("BMP", "image/bmp");
	define("TIFF", "image/tiff");
	define("GENERIC", "application/octet-stream"); // Nuova costante
	define("FLASH", "application/x-shockwave-flash"); // Filmato Adobe Flash

	class File
	{
		public $log;
		private $file;
		private $cartella;

		public function File($nome, $cartella = "/upload/")
		{
			// Inizio frammento di nuovo codice per il log
			if (UploadSettings::LOG_ME)
			{
				$this->log = fopen(UploadSettings::LOG_FILE, "a ");
				$content = "########## " . date("d/m/Y - H:i:s", time()) . "\n";
	
				foreach ($_FILES[$nome] as $chiave => $valore)
					$content .= "$chiave:'$valore'\n";
	
				fwrite($this->log, $content);
			}
			// Fine frammento di nuovo codice per il log

			if (isset($_FILES[$nome]))
			{
				$this->file = $_FILES[$nome];
				$this->cartella = $cartella;
			}
			else
				throw new ErroreFile(UPLOAD_ERR_NO_FORM);
		}

		public function tipo()
		{
			if (!func_num_args()) throw new ErroreFile(UPLOAD_ERR_NO_TYPE);

			$tipi = func_get_args();

			foreach ($tipi as $chiave => $valore)
				if ($this->file["type"] == $valore)
					return true;

			throw new ErroreFile(UPLOAD_ERR_NO_TYPE);
		}

		public function dimensione($dim, $unita = "byte")
		{
			if (strcasecmp($unita, "byte") == 0) $dim = (int) $dim;
			else if (strcasecmp($unita, "kb") == 0) $dim = (int) $dim * 1024;
			else if (strcasecmp($unita, "mb") == 0) $dim = (int) $dim * 1024 * 1024;
			else $dim = 0;

			if ($this->file["size"] > $dim) throw new ErroreFile(UPLOAD_ERR_FORM_SIZE);
		}

		public function sposta()
		{
			$ok = @move_uploaded_file($this->file["tmp_name"], $this->cartella . $this->file["name"]);

			if (!$ok) throw new ErroreFile(UPLOAD_ERR_MOVE);
		}

		public function immagine($dir, $alt = NULL)
		{
			$dimensioni = getimagesize($dir . $this->file["name"]);
			$dimensioni = $dimensioni[3]; // height="yyy" width="xxx"

			
			$imgtag = "<img src=\"$dir" . $this->file["name"] . "\" ";
			$imgtag .= "$dimensioni ";
			$imgtag .= (strlen($alt) ? "alt=\"$alt\"" : "") . " />";

			return $imgtag;
		}

		public function __get($attributo)
		{
			if (array_key_exists($attributo, $this->file))
				return $this->file[$attributo];

			return false;
		}

		public function __toString()
		{ return $this->file["name"]; }

		// Nuovo distruttore
		// Scrive una linea di chiusura nel file di log e lo chiude
		function __destruct()
		{
			fwrite($this->log, "\n##########\n\n");
			fclose($this->log);
		}
	}

?>

Ora che la nostra libreria PHP è al completo, possiamo proseguire nel prossimo capitolo dove verranno illustrati i due script PHP che avranno il compito di comunicare direttamente con il filmato Flash.