Dateien auslesen, prüfen und MySQL Anweisung

Do_0mi

Mitglied
Hi Leute,

ich wollte für mein Projekt, das einem Dateien auf dem Server anzeigt, nun für jede Datei eine Haken-Auswahl ob diese Datei veröffentlicht ist oder nicht machen. Das Formular dafür habe auch perfekt hinbekommen.
Jedoch habe ich bereits jetzt bei dem Aufabe des php-files Probleme.
Zuerst einmal eine Frage: Ist es sinnvoll und performant alle Dateien einzeln durchlaufen zu lassen und dann zu testen oder gibt es noch andere Möglichkeiten?

Meine Aufbau sollte folgender sein:
HTML:
while (DATEI HOLEN) {
SQL MACHEN
	IF(DATEI_in_DB_vorhanden && Nicht_per_Post_gesendet) {
		Datei aus DB rausnehmen!
	} elseif(Datei_in_DB_nicht_vorhanden && Per_Post_gesendet) {
		Datei in DB schreiben!
	}
}

Die Dateinamen werden, falls Haken gesetzt, per POST als "filename=public" gesendet.

Meine Anfänge:

PHP:
$dir = $_POST['dir'];

// POST: "blub.txt=public"

$handle = @opendir($dir);
while (false !== ($file = readdir($handle))) {
	$sql="SELECT * FROM `".precode."files` where filename=`".$file."` and filedir=`".$dir."`";
	$result=mysql_query($sql);
	while ($row = mysql_fetch_array($result)) {
		if (!isset($row['$file2']) && !isset($_POST['file'])) {
			// wenn in db vorhanden und haken nicht gesetzt
			// File aus Datenbank entfernen, weil es nicht aktiviert war!
			$sql="delete from ".precode."files where filename='".$_POST['file']."' and filedir='".$dir."'";
			mysql_query($sql);
		}
		elseif(isset($_POST['file']) ) {
			// Hakben gesetzt
			// File in Datenbank hinzufügen!
			$sql = "INSERT INTO `".precode."files` (`filename`, `filedir`)
			VALUES ('".$_POST['file']."', '".$dir."')";
			mysql_query($sql);
		}
	}
}

Er meldet "Warning: readdir(): supplied argument is not a valid Directory resource in /homepages/21/d76665669/htdocs/dariodomi/projekt_ezes/test/contents/publicfiles.php on line 15".
Neben diesem Problem bin ich mit den SQL-Anweisungen total am verzweifeln. Ich nehme mal an, dass "while ($row = mysql_fetch_array($result)) {" nicht sein muss, da es jeden Dateinamen ja eh nur einmal in der DB gibt.
Zudem ist "if(!isset($row['$file2']) ...)" wahrscheinlich auch nicht das richtige für "Datei in DB vorhanden", oder?

Über Hilfe freue ich mich wirklich sehr.

Gruß, Do_0mi
 
Hi,

Zuerst einmal eine Frage: Ist es sinnvoll und performant alle Dateien einzeln durchlaufen zu lassen und dann zu testen oder gibt es noch andere Möglichkeiten?

ich würde sagen, es ist einfach unnötig und natürlich nicht performant. Wenn Du aus dem Formular alle Dateinamen übergeben bekommst, die öffentlich sein sollen, kannst Du doch die nicht (mehr) öffentlichen mit einem einfachen DELETE-Statement aus der DB löschen:

Code:
DELETE FROM tabelle WHERE dateiname NOT IN (<Liste der öffentlichen Dateien>)

Wenn Dein Feld mit dem Dateinamen ein UNIQUE ist, kannst Du anschließend die fehlenden Dateien mit einem

Code:
INSERT IGNORE INTO tabelle (dateiname) VALUES ('datei1'), ('datei2'),...

einfügen.

Dabei solltest Du vorher natürlich die Daten aus dem Formular validieren, indem Du z.B. per [phpf]glob[/phpf] das Verzeichnis ausliest und mit den POST-Daten abgleichst.

Er meldet "Warning: readdir(): supplied argument is not a valid Directory resource in /homepages/21/d76665669/htdocs/dariodomi/projekt_ezes/test/contents/publicfiles.php on line 15".

Dann ist opendir() fehlgeschlagen und Du musst das mal debuggen. Stimmt der Pfad?

LG
 
Hi,

bin, deines Postes sei dank, auf eine andere Struktur gekommen:
HTML:
SQL MACHEN
while (Jeder DATEIName in der DB) {
	IF(Nicht per $_Post gesendet) {
		Aus DB rausnehmen
	}
}
while($_POST) {
	if (Dateinamen noch nicht in DB) {
		Dateiname in DB eintragen
	}
}

Nun habe ich meinen Quelltext auch schon soweit, dass es Dateien hinzufügt:
PHP:
$dir = ".";
$sql2="SELECT * FROM ".precode."files where filedir='".$dir."'";
$result2=mysql_query($sql2);
while ($row = mysql_fetch_array($result2)) {
	$file = $row['filename'];
	if (!isset($_POST['$file'])) {
		// File aus Datenbank entfernen, da es nicht mehr aktiviert war
		$sql="delete from ".precode."files where filename=".$_POST[$file]." and filedir=".$dir;
		mysql_query($sql);
	}
}
foreach($_POST as $key => $val) {
	while ($row = mysql_fetch_array($result2)) {
		if(!isset($row[$key])) {
			// File in Datenbank hinzufügen, da es aktiviert wurden ist
			$sql = "INSERT INTO `".precode."files` (`filename`, `filedir`)
			VALUES ('".$key."', '".$dir."')";
			mysql_query($sql);
		}
	}
}

Nun ist mir sowohl bei POST als auch bei GET aufgefallen, dass er bei
HTML:
<input type="checkbox" name="[dateiname]" value="public">
wenn im Quelltext z.B. name="So heisst die Datei.txt" steht, kommt bei der php datei statt der Lücken und Punkte "So_heist_die_Datei_txt" an.

Dadurch klappt dann natürlich nicht mehr das prüfen, ob die Datei bereits vorhanden ist oder ähnliches.

Woran liegt es bzw. gibt es eine Möglichkeit das zu verhindern?

(Mein Quelltext mit dem dateien rausnehmen hab ich noch nicht getesten)

Ich freu mich, wenn ihr noch andere Vorschläge für mich habt.


Gruß, Do_0mi
 
Hallo,

das liegt daran, dass "name", der variablen-name ist, über den php auf den value-wert zugreift. Variblen dürfen keine Leerzeichen enthalten, deswegen macht PHP die Unterstriche dahin.

Besser wäre sowas:

HTML:
HTML:
<input type="checkbox" name="datei[]" value="ich bin die erste datei.txt">
<input type="checkbox" name="datei[]" value="ich bin die zweite datei.txt">

Die "[]" hinter "datei" bedeuten das, datei als array übergeben wird.

PHP:

PHP:
foreach($_POST["datei"] as $key => $val) { 
 echo $val . "<br>";
}
würde dann
ich bin die erste datei.txt <br>
ich bin die zweite datei.txt
ausgeben
 
Zuletzt bearbeitet:
Hi,

bin, deines Postes sei dank, auf eine andere Struktur gekommen:

aber verstanden hast Du meinen Post anscheinend nicht. Eine Schleife brauchst Du höchstens, um am Anfang die Formulardaten zu validieren (aus Sicherheitsgründen). Wenn das passiert ist, musst Du nur noch die zwei Abfragen zusammensetzen, die die Schleifen überflüssig machen.

LG
 
aber verstanden hast Du meinen Post anscheinend nicht.
ne, hab ich auch nicht.

wie soll ich denn deiner meinung nach mein prüfen machen, wenn ich keine abfragen brauche?

... da meine tabelle nicht UNIQUE ist, geht dein "INSERT IGNORE INTO..." leider nicht.
der dateiname darf zwar nicht zweifach mit ordner "filedir=$dir" vorkommen, kann aber einmal per $dir=x und einmal unter $dir=y in die DB gespeichert werden. somit ist UNIQUE nicht möglich, oder seh ich das falsch?


Geht nicht einfach:
PHP:
// If-Abfrage um herauszufinden, ob eine Datei mit dem Namen bereits in der DB existiert WHERE filedir = $dir
$sql = "INSERT INTO `".precode."files` (`filename`, `filedir`) VALUES ('".$val."', '".$dir."')";

bzw. kann mir jem. sagen, wie ich prüfen kann, ob die datei existiert


Domi
 
Du kannst natürlich vorher ein SELECT count() mit den Angaben machen. Wenn du Null zurück bekommst, gibt es die Kobination noch nicht. Dann kannst du dein INSERT INTO machen.

somit ist UNIQUE nicht möglich, oder seh ich das falsch?

UNIQUE können auch mehrer Felder sein.
 
ne, hab ich auch nicht.

wie soll ich denn deiner meinung nach mein prüfen machen, wenn ich keine abfragen brauche?

Die Prüfung erfolgt halt in der Abfrage mittels WHERE-Klausel. Du kannst ja mit CONCAT() die Tabellenfelder filedir und filename zu einem String verknüpfen und in der Ausschlussliste die Dateien samt Verzeichnis reinschreiben, z.B.:

Code:
DELETE FROM tabelle 
   WHERE CONCAT(filedir, '/', filename) NOT IN ('dir1/oeffentlich.pdf', 'dir2/oeffentlich.pdf')

... da meine tabelle nicht UNIQUE ist, geht dein "INSERT IGNORE INTO..." leider nicht.
der dateiname darf zwar nicht zweifach mit ordner "filedir=$dir" vorkommen, kann aber einmal per $dir=x und einmal unter $dir=y in die DB gespeichert werden. somit ist UNIQUE nicht möglich, oder seh ich das falsch?

Wie Interritor schon sagt, kannst Du einen UNIQUE über mehrere Felder legen. ;)

LG
 
Zurück