Newsgroup: it.comp.www.php
Titolo: Parere: nome univoco per un file con date()

Lo scopo: 
generare un nome univoco per file immagine 
in modo da poter cancellare le stesse dal server 
quando il record MySql al quale sono associate viene cancellato 
senza possibilità di errore
$name = date('ymdis').$ext;
dove $ext è l'estensione.
Che ve ne pare? altre soluzioni?
Arjuna
-- 
Homo sum, humani nihil a me alienum puto.
 07/04/2004 13.04.49

ma scusa per un nome univoco usa una chiave autoincrementante di mysql
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (
http://www.grisoft.com
).
Version: 6.0.642 / Virus Database: 410 - Release Date: 24/03/2004

> ma scusa per un nome univoco usa una chiave autoincrementante di mysql
il nome deve essere genertato prima.
infatti devo utilizzarlo per poter spostare il file dalla cartella
temporanea a quella di destinazione.
il database registra solo il nome del file per poterlo richiamare
successivamente.
Arjuna 
-- 
Gnotis se auton.
 07/04/2004 13.58.28

 successivamente.
Ma ha ragione caciara. L'approccio corretto e' quello di utilizzare una
chiave autoincrementante, dato che l'immagine e' associata ad un record di
una tabella.
Inserisci il nuovo record, recuperane l'ID, e sposta il file nella cartella
di destinazione con il nuovo nome composto dall'ID stesso.
Non capisco dove sta l'impedimento, o per quale motivo si dovrebbe
"stravolgere" l'ordine di questi step.
-- 
C'ya,
  ZER0 :: coder.gfxer.webDesigner();
"When you have eliminated the impossible, whatever remains,
however improbable, must be the truth." (S.H.)


Quindi con $ext="jpg" otterresti ad esempio
$name = "200404075125.jpg"
Un ottimo sistema per sapere qual'è l'ultima immagine inserita, ma non vedo
alcun collegamento con il record al quale le immagini sono associate... :p
Se la tabella a cui fai riferimento contiene una chiave primaria costituita
da o più campi (cosa che mi auguro) potresti utilizzare questo metodo (se
non ci sono campi chiave aggiungi almeno un contatore (in MySQL, un campo
numerico (INT) con auto_increment impostato come chiave primaria))
$prefix = implode("_", $keys);
$name = $prefix . "_" . date("ymdhis") . "." . $ext;    // data e ora
esplicite
oppure
$name = $prefix . "_" . mktime($hour, $min, $sec, $month, $day, $year) . "."
. $ext;        // UNIX timestamp
dove $keys è un array con i valori dei campi della chiave primaria del
record a cui l'immagine è associata.
Se per esempio $keys = array("1", "pippo"), otterrai
$name = "1_pippo_20040407141142.jpg";
Quando cancelli il record, se l'operazione è andata a buon fine, cerchi
tutti i file che hanno prefisso $prefix e li cancelli: ovviamente devi
creare prefix prima di cancellare il record :)
Se non ti interessa salvare più immagini a seconda del loro data o
timestamp, utilizza come nome solo $prefix, così ti è più facile cancellare
il file, dato che ne esisterà uno solo per record: ho aggiunto al nome del
file la data di creazione dato che il tuo esempio la riportava.
Spero di esserti stato utile
Saluti
Luca Beltrame

Il problema č che l'elaborazione dell'immagine avviene prima dell'INSERT
nel database.
-- 
Gnotis se auton.
 07/04/2004 15.25.23

 nel database.
guarda qui
http://it.php.net/manual/it/function.mysql-insert-id.php
e occhio al warning
Ciao Gianfranzo
-- 
ICQ#: 21258924 Nick Gianfranzo
Home page 
http://www.gianfranzo.it
Gianfranzo č contro la guerra
"dopo tutto, gli angeli non sono altro che dei volatili" D. Pennac

 nel database.
Difatti io non ti consigliavo di osservare il valore restituito da
mysql_insert_id, ti dicevo solo di utilizzare i valori dei campi che
costituiscono la chiave primaria della tabella: avevo accennato all'uso di
contatori solo per semplicità nel caso la tabella fosse priva di chiave
primaria (fatto sconsigliabile nella maggior parte dei casi)
Non conoscendo il motivo per cui elabori l'immagine necessariamente prima di
inserire i dati nel db, evito di dirti di invertire le operazioni: rimane il
fatto che per collegare univocamente un file con un record, o utilizzi come
nome del file qualche operazione sui campi costituenti la chiave primaria,
oppure inserisci nella tabella un campo che faccia riferimento all'immagine
e che sia chiave univoca (altrimenti potresti finire col cancellare più
immagini invece di una), cosa che ti sconsiglio.
Un esempio di codice nel primo caso: chiave primaria non autoincrementante,
lettura del valore massimo della chiave e memorizzazione in una variabile
$valorechiave, incremento di uno di questa, creazione del nome
dell'immagine, inserimento nel db
if ($result = mysql_query("SELECT MAX(nomechiave) FROM nometabella;"))
{
    $rs = mysql_fetch_assoc($result);
    $valorechiave = $rs["nomechiave"];
    $prefix = crea_prefisso_da_chiave(++$valorechiave);
    $nomefile = $prefix ."." . $ext;
    /*
        creazione e salvataggio immagine
    */
    mysql_query("INSERT INTO nometabella (nomechiave, altricampi) VALUES " .
                         "($valorechiave, '$valorealtricampi');");
}
NB non testato anche perchè incompleto
Il dubbio che mi sorge su quest'implementazione riguarda il fatto che non so
con che strategia il server esegua richieste multiple... se arrivano
contemporaneamente due richieste per lo stesso script, e la loro esecuzione
procede parallelamente, la ricerca del massimo valore della chiave produrrà
lo stesso risultato, ovvero verranno create due immagini con lo stesso nome,
e oltretutto il secondo inserimento fallirà cercando di duplicare la chiave
primaria. In altri linguaggi di programmazione la cosa si potrebbe risolvere
con dei semafori, ma non mi pare che ciò sia possibile in PHP... smentitemi
pure mi interessa :)
Agh alla fine devo smentirmi e consigliarti l'inserimento prima del
salvataggio dell'immagine per questi problemi di concorrenza.... a meno che
tu non riesca a produrre dei valori sicuramente univoci da utilizzare come
chiavi primarie durante l'elaborazione dell'immagine (hashing sul contenuto
grezzo, maybe?)
LB

Se utilizzo date (a meno che non abbia la data dell'orologio del sistema
alterata) dovrei generare un nome file unico.
Non credo che valga la pena di essere maniaci. Potrei implementare anche
microtime... ma mi sembra un esagerazione.
Se poi dichiaro il campo dove viene registrato il nome del file 'unico'
allora non dovrei proprio avere problemi... o sbaglio?
Arjuna
-- 
Gnotis se auton.
 07/04/2004 17.41.43

 senza possibilità di errore
quindi se vuoi per forza utilizzare la data come dimensione univoca e non la
chiave del record, allora devi per forza salvare il nome dell'immagine come
campo del record stesso, altrimenti come fai a sapere, cancellando ad
esempio il record di indice 27 che la corrispondente immagine è
20040407175128.jpg? Deve esserci qualcosa che li relaziona... e non mi dire
che la data la salvi già, perchè non possiedo la sfera di cristallo e non
conosco la tabella in questione ^_^
LB

mmm, forse ho omesso una cosa importante (del resto era per me ovvia).
Il nome del file è caricato sul database nella stessa riga dell'indice a
cui fa riferimento.
ecco il codice di eliminazione:
$query = mysql_query("select immagine from gallery where
id={$_POST['da_eliminare']}");
list($image) = mysql_fetch_row ($query);
	  $file = "gallery/$image";
	  if (!unlink($file)) {
	  	die ('non sono riuscito ad eliminare'.$file);
	  }
  }
  $del_sql =  "DELETE FROM ". gallery WHERE id={$_POST["da_eliminare"]}"; 
 
 
Arjuna
-- 
Homo sum, humani nihil a me alienum puto.
 07/04/2004 18.09.13

 cui fa riferimento.
Ecco l'anello mancante!!! E' stato quasi un dialogo fra sordi ^_^
In tal caso se utilizzi una data (specialmente con microtime, dipende dal
carico di utenti del tuo sito, ovvero quanto spesso questa pagina venga
chiamata) come nome dell'immagine non dovresti avere problemi.
Devi ammettere però che se tu utilizzassi la chiave primaria della tabella
come nome dell'immagine otterresti due piccioni con una fava, ovvero un db
più "magro" (eviti di memorizzare una stringa/data) e dei nomi di immagine
SICURAMENTE univoci, indipendentemente dagli accessi alla pagina (i
conflitti da multitasking li risolve MySQL)
Dato che abbiamo discusso molto su questo argomento, mi permetti una
curiosità? Perchè l'elaborazione e soprattutto il salvataggio dell'immagine
deve avvenire prima dell'inserimento dei relativi dati su db? Quali sono i
vincoli per questa scelta implementativa?
LB

Non è molto che programmo e sono autodidatta.
Programmo ad istinto... imparo ogni giorno cose nuove, senza uno schema.
Sto costruendo un CSM per gestire il mio sito.
Principalmente il problema riguarda la gallery.
Uso un form per caricare i dati delle foto.
Ci sono tre input file per una foto e due thumbnail.
Al momento dell'upload i file immagine vengono processati.
Si verifica che il file esista.
Che sia un tipo valido.
Che non ecceda in Kb
Lo si nomina in base alla data e gli si assegna un posto sul server in base
al tipo.
Se non ci sono errori nell'upload allora faccio la query di INSERT.
L'unico serio vincolo che ho trovato è il poter verificare che non ci siano
errori prima dell'INSERT.
Secondo te mi potrebbe essere utile usare BLOB (spero si scriva così)?
Arjuna
-- 
Homo sum, humani nihil a me alienum puto.
 07/04/2004 19.00.25

 Secondo te mi potrebbe essere utile usare BLOB (spero si scriva così)?
solo se decidi di memorizzare le immagini su db invece che su filesystem:
puoi ottenere i dati grezzi con le funzioni di lettura della libreria gd
Quindi le operazioni da fare sarebbero queste ("quasi-pseudo-codice" in php)
$name = "immagine";        //nome dell'input file della form
$path = "/immagini/";        //percorso del file immagine (dinamico, nel tuo
caso)
$upload_ok = false;
$id = do_insert();
if (isset($_FILES[$name])) {
    $filename = $_FILES[$name]["name"];
    if ($filename != "" && check_format($_FILES[$name]["tmp_name"])) {
        $path = check_path($path);
        $filepath = $path . get_prefix($id) . "." . $ext;
        if (move_uploaded_file($_FILES[$name]["tmp_name"], $filepath))
$upload_ok = true;
    }
}
if (!upload_ok) {
    do_delete($id);
}
non scrivo le funzioni ma solo cosa dovrebbero fare
do_insert() // effettua l'inserimento e restituisce il valore del contatore
check_format($filename)    // verifica il formato MIME del file fornito
check_path($path)    // verifica l'esistenza del percorso fornito, se non
esiste lo crea, imposta i permessi di scrittura, e restituisce il percorso
con "/" finale se assente
get_prefix($id)    // ottiene il prefisso a partire dal contatore
do_delete($id)    // effettua l'eliminazione del record con chiave fornita
...vedi un po' se ti può servire questo mio "parto" ^_^
LB

Lo script per gestire gli upload è già pronto, devo solo verificare la
protezione per i mime type.
Non gradisco le funzioni gd perchè non governabili.
Per esempio per fare un ridimensionamento con crop a 150x150px le gd non ti
permettono di scegliere il taglio.
Per questo preferisco tagliare le thumbnail a mano
si perde molto molto più tempo ma non si potrebbe fare altrimenti.
Uso le gd su altri siti che non necessitano cotanta precisione.
Grazie mille... confronterò il tuo script con il mio per migliorarlo...
Arjuna
-- 
Gnotis se auton.
 08/04/2004 3.02.02

 Uso le gd su altri siti che non necessitano cotanta precisione.
Con le gd ti č possibile ottenere una sotto-immagine da un'immagine e poi
lavorare su questa, se non sbaglio (con imagecopyresampled, ad esempio):
ovviamente tale operazione verrebbe apllicata a tutte le immagini, quindi un
lavoro a mano risulterebbe certamente migliore, dato che permette di
inserire nella thumbnail solo la parte piů importante dell'originale.
Personalmente per un problema simile (un image-gallery a scopo autodidattico
:) ) ho utilizzato le azioni di Photoshop, con intervento dell'utente al
momento della selezione dell'area di taglio.
Una modifica al mio pseudo-script, per migliorare l'efficenza (non scrive su
db se non all'ultimo momento): le parti commentate vanno eliminate
//$upload_ok = false;
//$id = do_insert();
if (isset($_FILES[$name])) {
    $filename = $_FILES[$name]["name"];
    if ($filename != "" && check_format($_FILES[$name]["tmp_name"])) {
        $path = check_path($path);
        $id = do_insert();
        $filepath = $path . get_prefix($id) . "." . $ext;
        // if (move_uploaded_file($_FILES[$name]["tmp_name"], $filepath))
$upload_ok = true;
        if (!move_uploaded_file($_FILES[$name]["tmp_name"], $filepath))
do_delete($id);
    }
}
//if (!upload_ok) {
//    do_delete($id);
//}
Buon lavoro!
LB

 momento della selezione dell'area di taglio.
Io invece uso direttamente una taglierina impostata a 150 x 150 px in
questo modo mi ricampiona l'immagine a seconda del taglio che voglio...
Molto ma molto più rapido...
Vuoi valutarmi il sito che sto costruendo?
Arjuna
-- 
Homo sum, humani nihil a me alienum puto.
 08/04/2004 12.12.24