[PHP] Selezionare immagini directory non presenti in db

miagy

Utente Attivo
2 Nov 2014
56
0
6
Ciao ragazzi,
vi scrivo perché avrei urgentemente del vostro aiuto. Sostanzialmente nel mio sito ho una directory /immagini/Files all'interno della quale ci sono una cosa cosa 8000 file immagini.
Queste immagini fanno riferimento a una tabella nel mio database chiamata File_Utente dentro cui c'è un campo chiamato Immagine_File.

Ecco, se io volessi fare una lista di tutte quelle immagini presenti nella directory /immagini/Files ma che non sono memorizzate nel campo Immagine_File della tabella File_Utente, quale sarebbe la query corretta?

Ho provato a cercare sul forum ma non ho trovato nulla :(
 

marino51

Utente Attivo
28 Feb 2013
2.589
130
63
Lombardia
Ecco, se io volessi fare una lista di tutte quelle immagini presenti nella directory /immagini/Files ma che non sono memorizzate nel campo Immagine_File della tabella File_Utente, quale sarebbe la query corretta?
non conosco un metodo che relazioni direttamente il contenuto di una directory con una tabella del database

penso che la soluzione migliore sia,
1) creare una nuova tabella nel db (tableB)
2) inserire nella nuova tabella tutti i nomi dei files (8000) ottenuti dalla lista della directory
3) selezionare le differenze con la query
Codice:
select <colonne da estrarre>
from tableA A
right join tableB B
on A.key = B.key
where A.key is null
4) cancellare la nuova tabella quando non più necessaria

tableA è la tabella già presente nel database

sufficiente ?
 

miagy

Utente Attivo
2 Nov 2014
56
0
6
non conosco un metodo che relazioni direttamente il contenuto di una directory con una tabella del database

penso che la soluzione migliore sia,
1) creare una nuova tabella nel db (tableB)
2) inserire nella nuova tabella tutti i nomi dei files (8000) ottenuti dalla lista della directory
3) selezionare le differenze con la query
Codice:
select <colonne da estrarre>
from tableA A
right join tableB B
on A.key = B.key
where A.key is null
4) cancellare la nuova tabella quando non più necessaria

tableA è la tabella già presente nel database

sufficiente ?

Ti ringrazio tantissimo, effettivamente è una soluzione a cui non avevo minimamente pensato. Ho già seguito le tue dritte e ho definitivamente risolto il problema.

Solo un'ultima cosa, questo per mera curiosità mia: se io volessi fare un controllo non su 2 tabelle ma su 3, la sintassi quale sarebbe? Parlando in parole semplici: se OGG è presente in Tabella A e Tabella B ma NON in Tabella C = Risultato
 
Ultima modifica:

marino51

Utente Attivo
28 Feb 2013
2.589
130
63
Lombardia
con 3 tabelle si può usare una query simile,
ma occorre conoscere come gestire l'assenza tra tabella a e b e poi l'assenza nella tabella c
con un esempio dei contenuti delle 3 tabelle e dei risultati attesi, posso essere più specifico
 

miagy

Utente Attivo
2 Nov 2014
56
0
6
Provo a trascrivere un esempio simile: ho 3 tbl di cui riporto i campi che devo estrarre/devo confrontare

Ordini
- ID (1,2,3,4,5,6,7,8)
- Nome (bla bla bla bla)

Acquisti
- IDOrdine (1,3,5,7)
- Quantita (bla bla bla)

Clienti
- IDOrdine (1,2)
- Nominativo

Se io volessi selezionare tutti gli ID (campo comune) di Ordini che non sono presenti in Acquisti e Clienti (quindi 4, 6 e 8), che sintassi dovrei usare?
 

marino51

Utente Attivo
28 Feb 2013
2.589
130
63
Lombardia
upload_2019-4-14_22-3-58.png


lascio a te trovare le altre 2 forme con cui si può scrivere la stessa query

WHERE o.id NOT IN

WHERE o.id NOT EXISTS
 

marino51

Utente Attivo
28 Feb 2013
2.589
130
63
Lombardia
scusa se non l'ho scritto nel post precedente,
il simbolo "@" anteposto al nome delle tabelle identifica tabelle temporanee in sql-server,
tabelle che esistono solo con la/e query collegata/e
terminata l'esecuzione della/e query, vengono cancellate automaticamente
 

miagy

Utente Attivo
2 Nov 2014
56
0
6
Okay, ti disturbo solo per un ultimo dubbio.
Sostanzialmente faccio tutto quello che hai detto ed effettivamente mi compaiono tutti i file che non sono valorizzati all'interno delle due tabelle:

PHP:
$MySql = "SELECT * FROM T1
LEFT JOIN T2
ON T1.ID = T2.ID2
LEFT JOIN T3
ON T1.ID= T3.ID3
WHERE T2.ID2 IS NULL
AND T3.ID3 IS NULL";

$Result = mysql_query($MySql);
while ($rs = mysql_fetch_array($Result)) {  ?>

<tr>
<td align=center width="20%" style="border:1px solid #888888;"><?= htmlspecialchars($rs['File']) ?></td>

<td align=center width="5%"><form method="post" name="cancellaselezione" action="elenco_obs.php?op=cancellaselezione">
 <input type="checkbox" name="item[]" value ="<?=$rs["ID"] ?>"></td></tr>
<?
}
$rs->close;
mysql_free_result($Result);
?>


</table><br><br>
<input type="button" value="Seleziona tutto" onclick="SelezTT()" class="ares"><br>
<input type="submit" name="cancellaselezione" class="ares" Value="Cancella selezione"></form>
Il problema nasce quando, una volta selezionato tutti gli elementi questo mi elimina anche i file che non compaiono nella lista.

PHP:
if ($op=="cancellaselezione") {
$item = $_POST['item'];
if( is_array($item) )
{
echo 'Elementi selezionati: ' . count( $item ) . '<br/>';
foreach ( $item as $value ) {

$basedir = 'img/file';

$fileregex='/\.(png)$/';

if ($basedir and is_dir($basedir) and $fileregex) {

   $all = opendir($basedir);
   while ($value = readdir($all)) {
         if (preg_match($fileregex,$value)) {
        
                unlink($basedir.'/'.$value);
                echo '<font color=red>';
                echo $value;
                echo ' cancellato!</font>';
            echo '<br>';
         }
   }
}
closedir($all);
unset($all);

    }
  }
}
 

marino51

Utente Attivo
28 Feb 2013
2.589
130
63
Lombardia
ho guardato il solo html, mi sembra che lo hai postato in parte,
ma credo che la sequenza degli oggetti contenuti non sia corretta,
perché apri un form in ogni "tr" ma ne chiudi uno solo alla fine

la sequenza corretta per la soluzione "form con tabella" dovrebbe essere
form con action
table
tr
visualizzazione del file
(potresti mettere anche un campo hidden con informazioni specifiche del file)
checkbox
/tr

al termine delle righe
/table
bottone submit
/form

in questo modo lo script php potrebbe scorrere le "righe" e cancellare solo quelle che hanno checkbox selezionato

se invece vuoi usare la soluzione "riga con form",
devi aprire e chiudere il form nella riga stessa nella riga stessa
mettendo nella riga le info del file, come per la soluzione precedente
ed anche un submit che possa attivare lo script php per quel form

rivedi html secondo la soluzione che desideri (form con tabella o riga con form) e se puoi/vuoi, postalo interamente

ps, questa istruzione mi farebbe pensare che lavori con la soluzione form e tabella
echo 'Elementi selezionati: ' . count( $item ) . '<br/>';
ma nell'html vedo una situazione mista ….
 

miagy

Utente Attivo
2 Nov 2014
56
0
6
Sì, perdonai.
Ho aggiustato ma il risultato è il medesimo. Me li visualizza in maniera corretta (nella lista) ma all'atto della cancellazione non fa nessuna differenza.

PHP:
<script type="text/javascript">
function SelezTT()
{
    var i = 0;
    var cancellaselezione = document.cancellaselezione.elements;
    for (i=0; i<cancellaselezione.length; i++)
    {
        if(cancellaselezione[i].type == "checkbox")
        {
            cancellaselezione[i].checked = !(cancellaselezione[i].checked);
        }
    }
}
</script>
</head>
<body>

<center>

<?
#-------- CODICE PER LA CANCELLAZIONE DEI FILE SELEZIONATI --------
if ($op=="cancellaselezione") {
$item = $_POST['item'];
if( is_array($item) )
{
echo 'Elementi selezionati: ' . count( $item ) . '<br/>';
foreach ( $item as $value ) {

$basedir = 'img/file';

$fileregex='/\.(png)$/';

if ($basedir and is_dir($basedir) and $fileregex) {

   $all = opendir($basedir);
   while ($value = readdir($all)) {
         if (preg_match($fileregex,$value)) {
     
                unlink($basedir.'/'.$value);
                echo '<font color=red>';
                echo $value;
                echo ' cancellato!</font>';
            echo '<br>';
         }
   }
}
closedir($all);
unset($all);

    }
  }
}

?>
<form method="post" name="cancellaselezione" action="elenco.php?op=cancellaselezione">
<table border="0" bordercolor="#888888" cellspacing=2 cellpadding=2 width=570>
<tr>
    <td colspan=4 align=center style="border:1px solid #888888;"><font style="font-size:12px;">File obsoleti</font><br><br>
</td>
</tr>
<tr>

<?

$MySql = "SELECT * FROM T1
LEFT JOIN T2
ON T1.ID = T2.ID2
LEFT JOIN T3
ON T1.ID= T3.ID3
WHERE T2.ID2 IS NULL
AND T3.ID3 IS NULL";

$Result = mysql_query($MySql);
while ($rs = mysql_fetch_array($Result)) {  ?>


<td align=center width="20%" style="border:1px solid #888888;"><?= htmlspecialchars($rs['Img']) ?></td>

<td align=center width="5%">
 <input type="checkbox" name="item[]" value ="<?=$rs["Img"] ?>"></td></tr>
<?
}
$rs->close;
mysql_free_result($Result);
?>


</table><br><br>
<input type="button" value="Seleziona tutto" onclick="SelezTT()" class="ares"><br>
<input type="submit" name="cancellaselezione" class="ares" Value="Cancella selezione">
</form>
</table>
</body>
 
Ultima modifica:

marino51

Utente Attivo
28 Feb 2013
2.589
130
63
Lombardia
io farei così,
PHP:
<?php
if ( empty($_GET) or empty($_POST) ) {  //non ricevo dati che servono, visualizzo il form
?>
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function SelezTT()
{
    var i = 0;
    var cancellaselezione = document.cancellaselezione.elements;
    for (i=0; i<cancellaselezione.length; i++)
    {
        if(cancellaselezione[i].type == "checkbox")
        {
            cancellaselezione[i].checked = !(cancellaselezione[i].checked);
        }
    }
}
</script>
</head>
<center>
<body>
<form method="post" name="cancellaselezione" action="elenco.php?op=cancellaselezione">
  <table border="0" bordercolor="#888888" cellspacing=2 cellpadding=2 width=570>
    <tr>
      <td colspan=4 align=center style="border:1px solid #888888;">
        <font style="font-size:12px;">File obsoleti</font><br /><br />
      </td>
    </tr>
<?php
$query = "SELECT * FROM T1
LEFT JOIN T2
ON T1.ID = T2.ID2
LEFT JOIN T3
ON T1.ID= T3.ID3
WHERE T2.ID2 IS NULL
AND T3.ID3 IS NULL";

// qui devo inserire la connessione al db

$result = mysql_query($query);
while ($rs = mysql_fetch_array($result)) {
?>
    <tr>
      <td align=center width="20%" style="border:1px solid #888888;"><?= htmlspecialchars($rs['Img']) ?></td>
      <td align=center width="5%">
        <input type="checkbox" name="item[]" value ="<?= $rs["Img"] ?>">
      </td>
    </tr>
<?php
}
$rs->close;
mysql_free_result($result);
?>
  </table><br /><br />
  <input type="button" value="Seleziona tutto" onclick="SelezTT()" class="ares"><br />
  <input type="submit" name="cancellaselezione" class="ares" Value="Cancella selezione">
</form>
</center>
</body>
</html>
<?php
}
else { // ho ricevuto i dati, sia $_GET che $_POST quindi eseguo l'operazione richiesta

    //-------- CODICE PER LA CANCELLAZIONE DEI FILE SELEZIONATI --------
    if ( !empty($_GET['op']) and $_GET['op'] == "cancellaselezione" ) {
        echo "ho ricevuto " . $_GET['op'] . "<br />";

        if ( !empty($_POST['item']) ) {
            echo "ho ricevuto item in post" . "<br />";

            $item = $_POST['item'];
            if( is_array($item) ) {
                echo "item é array" . "<br />";

                $sel = count( $item );
                if ( empty($sel) ) {
                    die("non hai selezionato elementi");
                }
                echo 'Elementi selezionati: ' . $sel . "<br />";

                $basedir = 'img/file';

                $fileregex='/\.(png)$/';

                if ($basedir and is_dir($basedir) and $fileregex) {
                    echo "ho trovato la directory " . $basedir . "<br />";

                    foreach ( $item as $value ) {
                        echo "file selezionato " . $value . "<br />";

                        if ( !unlink($basedir . "/" . $value) ) {
                            echo "Errore generato nella concellazione del " . $value;
                        }
                        else {
                            echo "<font color=red>" . $value . " cancellato !</font>" . "<br />";
                        }
                    }
                }
            }
        }
    }
}
?>
ti ho lasciato un po' di echo così controlli i passaggi
(non ho controllato mysql perché non é sul mio computer, ma lo script funziona bypassando mysql)
il risultato,
upload_2019-4-18_22-9-11.png

upload_2019-4-18_22-10-6.png

upload_2019-4-18_22-10-43.png

upload_2019-4-18_22-11-33.png

se hai ancora problemi fatti vivo