Erkennen ob Eintrag in MySQL DB gelöscht wurde

DieTa

DieTa

Aktives Mitglied
Thread Starter
Dabei seit
17.09.2003
Beiträge
3.388
Reaktionspunkte
32
Guten Morgen,

ich möchte über eine Funktion erkennen ob ein Eintrag in der Datenbank gelöscht wurde. Hintergrund ist, dass ich dem User, wenn er ein Foto hochgeladen hat und dieses gelöscht wurde gerne mitteilen würde, wenn er das nächste Mal die Seite betritt, dass der die "Terms-of-use" gebrochen hat und bitte darauf achtet, was er hochgeladen hat.

Momentan sieht mein Ansatz so aus:

PHP:
<?php
	if(isset($_COOKIE['fileaddress']))
{
	include('config.inc.php');
  $db2 = mysql_select_db($db_name);
  $cookieinhalt = $_COOKIE['fileaddress'];
  $result=mysql_query("SELECT * FROM spongedpics WHERE rndid = '$cookieinhalt'"); // WHERE file_id='$file_id'");
        
    while ($array = mysql_fetch_array($result,MYSQL_ASSOC)) 
    {
		if ($array["rndid"] = "") {
		echo "<div class='warning'><b>WARNING!<br>The picture with your ID <span style='color:#ffb400';>" . $cookieinhalt . "</span>,<br>that you have uploaded at your last visit was <b>DELETED</b> because you broke the terms-of-use!<br>";
		echo "<br>Please read them again and handle with care!</div>";
		}
		else
		{	
		echo "This is the last picture that you have uploaded<br><br>";
		echo "<a href='http://content.spongedpics.com/". $array['filename'] ."' target='blank'><img src='http://content.spongedpics.com/resized_" . $array['filename'] ."' border='0'></a>";
		}
	}
}
else
{
	echo "You have not uploaded any picture with this computer/browser yet or you have deleted your cookies since your last visit.<br>";
}
?>

Was ich jetzt nicht hinbekomme ist der Abruf vom Typ "Wenn Eintrag $rndid nicht vorhanden ist, dann zeige mir diesen Text an".

Vermutlich habe ich einfach Tomaten auf den Augen :)
 
Versteh ich das richtig? Du gibt's dem User die Möglichkeit, was zu löschen und willst ihn dann nachher drauf hinweisen, dass das laut Terms-of-use nicht erlaubt ist? :kopfkratz:
 
Code:
if ($array["rndid"] = "") {

ist kein Vergleich, sondern eine Zuweisung !

Zudem steht in der Query:

Code:
...WHERE rndid = '$cookieinhalt'"

das heißt Deine if-clause kann bei Vergleich ur true sein, wenn auch $cookieinhalt leer ist. So gewollt?
 
nein, das soll dem user bescheid geben wenn ein bild von den admins gelöscht wurde weil es gegen die terms verstoßen hat, oder DieTa?
 
Von Hause aus merkt sich das MySQL nicht, außer Du hast das Logging eingeschaltet und wertest die Log-Datei aus.

Ich weiss nicht wie Du es im Gesamten realisiert hast, aber ich würde folgenden Ansatz gehen:
Ich gehe davon aus, dass jedes Bild aus zwei Komponenten besteht, aus den Meta-Daten, die in der Datenbank stehen, und den eigentlichen Daten, die entweder im Dateisystem liegen (meine Variante) oder ebenfalls in der Datenbank. Wenn jetzt ein Bild gelöscht wird, werden nur die eigentlichen Daten gelöscht. Die Metadaten dagegen verbleiben in der Datenbank, bekommen aber den Vermerk, dass das Bild den Status gelöscht hat. Dies hat den Vorteil, dass Du damit in einem einfachen Rahmen verhindern kannst, dass "gebannte" Bilder erkannt werden können. Dazu vermerkst Du in den Metadaten zusätzlich einen Hash-Wert über das Bild. Diesen brauchst Du nur vergleichen, wenn der selbe Benutzer ein Bild hochladen möchte. Damit verhinderst Du, dass ein Nutzer das selbe Bild unter einem anderen Namen nocheinmal hochlädt. Wenn es jetzt noch ein passenden Hash-Algorithmus gibt, der bei ähnlichen Bildern gleiche Hash-Werte erzeugt, würden auch ähnliche Bilder und nicht nur selbe Bilder erkannt werden. Leider weiss ich nicht ob es solche Hash-Algorithmen in der Bildverarbeitung existieren. Dazu müsste man sich mit dem Thema mehr auseinandersetzen.
 
@BuRN_Colonie: Eh ja richtig!

Sorry Saugkraft - habe mich falsch ausgedrückt :)

@Wegus:
Wenn $cookieinhalt leer ist, wird das ganze ja gar nicht angezeigt. Es geht geht mir ja um die Abfrage, ob 'rndid' überhaupt existiert.
 
nein, das soll dem user bescheid geben wenn ein bild von den admins gelöscht wurde weil es gegen die terms verstoßen hat, oder DieTa?
Ah, jetzt, ja. Eine Insel. :)

Na wo liegt das Problem? Boolsches Datenbankfeld namens terms, das gesetzt wird, wenn eben das passiert ist. Ist doch viel einfacher. Wozu umständlich über DB Logging arbeiten? Das hat ganz andere Aufgaben.
 
Von Hause aus merkt sich das MySQL nicht, außer Du hast das Logging eingeschaltet und wertest die Log-Datei aus.

Ich weiss nicht wie Du es im Gesamten realisiert hast, aber ich würde folgenden Ansatz gehen:
Ich gehe davon aus, dass jedes Bild aus zwei Komponenten besteht, aus den Meta-Daten, die in der Datenbank stehen, und den eigentlichen Daten, die entweder im Dateisystem liegen (meine Variante) oder ebenfalls in der Datenbank. Wenn jetzt ein Bild gelöscht wird, werden nur die eigentlichen Daten gelöscht. Die Metadaten dagegen verbleiben in der Datenbank, bekommen aber den Vermerk, dass das Bild den Status gelöscht hat. Dies hat den Vorteil, dass Du damit in einem einfachen Rahmen verhindern kannst, dass "gebannte" Bilder erkannt werden können. Dazu vermerkst Du in den Metadaten zusätzlich einen Hash-Wert über das Bild. Diesen brauchst Du nur vergleichen, wenn der selbe Benutzer ein Bild hochladen möchte. Damit verhinderst Du, dass ein Nutzer das selbe Bild unter einem anderen Namen nocheinmal hochlädt. Wenn es jetzt noch ein passenden Hash-Algorithmus gibt, der bei ähnlichen Bildern gleiche Hash-Werte erzeugt, würden auch ähnliche Bilder und nicht nur selbe Bilder erkannt werden. Leider weiss ich nicht ob es solche Hash-Algorithmen in der Bildverarbeitung existieren. Dazu müsste man sich mit dem Thema mehr auseinandersetzen.

Die Herangehensweise hat was! Da könnte ich eigentlich eine einfaches Feld definieren die sagt: "Ok" oder "Deleted" und dann daraufhin abfragen.

Bisher handhabe ich es allerdings so, dass die gelöschten Bilder auch auf einen Schlag gleich auch die DB-Einträge löschen, denn wenn der Service (www.spongedpics.com) einmal läuft werden das ganz schnell SEHR viele Einträge werden.
 
Ah, jetzt, ja. Eine Insel. :)

Na wo liegt das Problem? Boolsches Datenbankfeld namens terms, das gesetzt wird, wenn eben das passiert ist. Ist doch viel einfacher. Wozu umständlich über DB Logging arbeiten? Das hat ganz andere Aufgaben.

Nee nee DB-Logging verwende ich dafür nicht.

"terms" sagt mir jetzt nix, aber ich glaube das ist die gleiche Variante wie das Feld was ich im Post eben gepostet habe nur eben mit "true/false" statt "Ok/Deleted" :) Gut - ist natürlich sauberer und eine ideale Anwendung für Boolean.
 
dann ist isset Dein Freund:

http://de3.php.net/manual/de/function.isset.php


Da PHP Typenlos ist, ist =="" keine ausreichende Prüfung auf nicht Vorhandensein! Eine Variable $test['123'] ist nicht existent wenn:

Code:
$test['123']=null;
// oder
unset($test['123']);

ausgeführt wurde! In Deinem Fall ist sie nur leer! Soll eine Typbindung bei leerem String erfolgen muß sogar

$test['123]==="";

dort stehen!
 
@wegus: Zu gut Deutsch - das geht doch und ich habe jetzt die Qual der Wahl - Daten behalten (s.o.) oder Deine Variante nehmen - spricht mit "isset" arbeiten.

Was würdet Ihr machen? Daten behalten oder rigeros löschen?
 
Bisher handhabe ich es allerdings so, dass die gelöschten Bilder auch auf einen Schlag gleich auch die DB-Einträge löschen, denn wenn der Service (www.spongedpics.com) einmal läuft werden das ganz schnell SEHR viele Einträge werden.
Hoffst Du ;).
Man kann Einträge, die ein bestimmtes Alter haben, löschen. Denn wenn es jemand wieder versucht, wird er/sie es meistens innerhalb eines kurzen Zeitraums versuchen.

Unabhängig davon, hätte mein Vorschlag in meinen Augen weitere Vorteile. Bedenke, dass es langfristig besser ist, ein System zu haben, dass automatisch einmal gelöschte/gebannte Bilder erkennt. Denn das reduziert an dieser Stelle den Administrationsaufwand. Außerdem könnte man davon ausgehen, dass ein und das selbe interessante Bild von mehreren Nutzern hochgeladen wird. Mit einem guten Hashing-Algorithmus könnte man das erkennen. Wenn ein solcher Fall erkannt wird, verweissen die Metadaten dann auf die vorhandenen Bilddaten und sparen damit Speicherplatz, der knapp werden könnte, wenn der Service (www.spongedpics.com) einmal läuft ;)
 
Bisher handhabe ich es allerdings so, dass die gelöschten Bilder auch auf einen Schlag gleich auch die DB-Einträge löschen, denn wenn der Service (www.spongedpics.com) einmal läuft werden das ganz schnell SEHR viele Einträge werden.
Aus Datenbanksicht keine gute Idee. Im Übrigen.. mySQL schafft sowas ohne Probleme. Ist ne Frage der DB-Organisation. ;) Die paar gelöschten Einträge schaffen keinen Platz, der irgendwie signifikant wäre.

Wenn du Platz sparen willst, kannst du ggf. Indexdaten von Nutzdaten trennen und in zwei Tabellen packen. Aber da die Datei eh im Dateisystem liegt, ist das auch nur Makulatur.

Ich kenn die Spezifikationen von mySQL nicht wirklich, aber bei ner anständig normalisierten Datenbank kriegst du selbt mit mehreren Millionen Einträgen keine Performanceprobleme. Wenn du alte Einträge tatsächlich endgültig rauswerfen willst, bieten sich Timestamps an. Die kannst du mit ner Wartungsroutine abfragen und dann gelegentlich alte Einträge löschen.

Auf Datenbankseite würde ich sowas aber auf keinen Fall lösen, sondern über externe Wartungsroutinen. Du musst immer bedenken.. Die DB an sich ist leistungsfähiger als man glauben mag. Langsam wird es durch den draufgesetzten PHP-Code, bzw. durch Abfragen aller Datensätze in Schleifen oder ähnlichem Spaghetticode.

Edit:
"terms" sagt mir jetzt nix, aber ich glaube das ist die gleiche Variante wie das Feld was ich im Post eben gepostet habe nur eben mit "true/false" statt "Ok/Deleted" Gut - ist natürlich sauberer und eine ideale Anwendung für Boolean.
Genau. "terms" war jetzt nur ein Beispiel für den Namen des Feldes. Soll halt per Boolean anzeigen, ob das Bild vom Admin gelöscht wurde. Da kann dann ggf. auch noch ein Hash-Wert dazu. (Find den Vorschlag übrigens auch gut.)
Die Hash-Werte würde ich aber in ner anderen Tabelle speichern, damit du routinemäßig daraufhin das Dateisystem untersuchen kannst. Also ein weiteres Feld mit einem Index der Hashwertverstoßtabelle ;).
 
Ok vielen Dank für Euer Statement und Euren Lösungsansatz! Ich werde es so umsetzen und einfach einen neuen Eintrag (boolean) einbauen. Dann kann ich auch direkt auf der Startseite besser aussortieren ;)

Dann führe ich halt ein sauberes Logbuch per MySQL-DB :p

Danke!!
 
ich würd auch mit nem Flag valid/invalid arbeiten und dann zwei Sichten verwenden. Die Tabelle zeigt alle Einträge und der view mit valid=1 nur die gültigen.

@DieTa: ich dachte Du willst prüfen ob das Array-Element gesetzt ist oder nicht? Dann ist Deine Prüfung aber falsch!
 
ich würd auch mit nem Flag valid/invalid arbeiten und dann zwei Sichten verwenden. Die Tabelle zeigt alle Einträge und der view mit valid=1 nur die gültigen.

@DieTa: ich dachte Du willst prüfen ob das Array-Element gesetzt ist oder nicht? Dann ist Deine Prüfung aber falsch!

Im Grunde genommen fällt das ja dann flach, wenn ich einfach mit dem "terms" (oder wie auch immer ich das nenne) einfach prüfen kann ob das Bild gelöscht wurde oder nicht, oder?

Übrigens: Die Bilder sind im FS gespeichert. In der DB wird eine RandomID und der (modifiziert: sprich leerzeichen-entfernte) Dateiname eingetragen. Hinterher wird alles dynamisch wieder zusammengepuzzelt.
 
Dann führe ich halt ein sauberes Logbuch per MySQL-DB :p
Du musst das immer so sehen: eine Datenbank ist ein Dokumentationswerkzeug, keine Datenablage.

Ein paar Grundregeln:
- Zerlege jeden Prozess in Einzelschritte (z.B. das Hochladen eines Bildes) und guck dir an, welche Daten bei jedem Einzelschritt anfallen. Die strukturierst du dann und gestaltest die Datenbank dementsprechend.
- Die kleinste, bedeutungstragende Einheit, die ggf. abgefragt oder getrennt ausgewertet werden soll, sollte eine eigene Tabelle bekommen und per Verweis angesprochen werden. Das nennt man dann Normalisieren. Steigert die Geschwindigkeit und Übersichtlichkeit enorm.
- Datensätze sollten nach Möglichkeit nicht gelöscht werden. Wozu auch? Der Speicherplatz ist unerheblich, die Geschwindigkeit leidet fast überhaupt nicht, aber ggf. sind Daten weg, die später mal benötigt werden. Bei Datenbanksystemen wie mySQL liegt die Performance im internen Aufbau, d.h. wenn du nur bestimmte Datensätze brauchst, machst du das per SELECT. Den Rest erledigt die Datenbank.

Und zu guter Letzt.. Wenn deine Datenbank nur 2 oder 3 Tabellen hat, kann das Absicht sein. Meistens ist es dann aber keine Datenbank, sondern einfach eine Datenablage ohne Struktur. :p

Viel Erfolg weiterhin. :) Ich bin mal gespannt.
 
Ich war gerade mal auf dem Klo. Da kommen mir immer die besten Einfälle, weil da hat man sonst nix anderes zu tun :D.

Ich würde auf 3 verschiedene Hash-Werte kommen. Zwei allgemeine Hash-Werte aus dem Bereich der Erkennung von Datenveränderungen und einen speziellen aus der Bildverarbeitung zur Erkennung von Ähnlichkeiten.
Der erste geht über die gesamte Bilddatei und erkennt selbe Bilddateien. Der zweite geht nur über den Bildinhalt, dazu müsste man z.B. die Meta-Daten in JPGs herausfiltern. Damit erkennt man das selbe Bild, was aber einem Bildbearbeitungsprogramm mal kurz aufgemacht wurde. Gegebenenfalls muss dazu aber die Bilddaten überarbeiten, denn in JPGs zum Beispiel können die Bilddaten auf verschiedenste Weise gespeichert werden (eigentlich gibt es zwei Varianten, als Block und als Stripes). Der dritte Algorithmus erkennt dann halt ähnliche Bilder, die z.B. durch Mehrfachkomprimierung, Kontraständerung, Schärfeänderung und ähnliches auftreten können.
 
Hallo Ihr beiden,

@Saugkraft: Hast mich ja überzeugt :p - Vielleicht sollte ich mal erwähnen, dass ich MySQL nur rudimentär beherrsche und mir alles per Google-Suche beigebracht habe? :) Das soll jetzt keine Ausrede sein, sondern ist eine Tatsache.

Hier mal die Struktur der DB (ich seh Euch jetzt schon die Hände über dem Kopf zusammenschlagen *g*):
Code:
 file_id   	int(5)     	auto_increment   	# ID
 filename  	text 	  				# Dateiname
 user_ip  	text 	  				# IP des Users
 datum  	text 	  				# Datum des Uploads DD:MM:YYYY
 zeit  		text 	  				# Zeitpunkt des Uploads HH:MM:SS
 browser  	text 	  				# Browser eben
 sprache  	text 	  				# Sprache des Browsers
 groessew  	int(5) 	  				# Größe des Bildes WIDTH
 groesseh  	int(5) 	  				# Größe des Bildes HEIGHT
 groessek  	int(10) 				# Größe des Bildes KByte
 typ  		text   					# Dateityp
 oname  	text 					# Originalname (vor Entfernung der Leerzeichen)
 rndid  	text 					# Personal Random ID - wird in den Dateinamen eingebaut
 referer  	longtext				# Woher kommt der User?
 hostname  	text 					# Hostname
 httpvia  	text 					#
 httpforw  	text 					#
 httpuav  	text 					#
 httpxfor  	text 					#
 httpcache  	text 					#
 httpproxy  	text 					# Proxyserverinformationen
 moderated  	int(1) 					# Wurde das Bild moderiert? Ja = 1 / Nein = 0

moderated int(1) deswegen, weil phpMyAdmin mir hier kein (?) boolean anbietet, aber wenn ich mit 0 & 1 arbeite kommt ja das gleiche bei raus...

@pingu: Auf'm Pott kommen mir auch immer die besten Ideen :p
Wie erstellt man denn so ein Hash? Ich kenn nur den MD5-Hash den man zur Datenübertragungsverfikation (geiles Wort) verwendet.
 
Och, die DB scheint so ganz okay zu sein. Ich vermute aber, dass du irgendwann mal Daten auslagern wirst. Wenn bestimmte Werte immer wieder auftauchen. So z.B. Browsertypen. In dem Fall würdest du halt eine Tabelle Browser anlegen, bei der Safari z.B. die ID 1 bekommt, Firefox die 2 etc. Dann kommt in die obige Tabelle eben immer nur die id des jeweiligen Browsers. Im Moment sehe ich da aber noch keinen wirklichen Bedarf. Die 5 Browser können auch da mit rein, dafür muss nicht zwingend ne extra Tabelle her. Wird aber z.B. bei einer Benutzerverwaltung interessant.

Vielleicht wäre eine Tabelle mit "blacklisted" Hash-Werten sinnvoll. Jedesmal wenn ein Admin ein Bild löscht, kommt der Hash-Wert in die böse Tabelle. Beim Upload kannst du dann direkt vergleichen, ob der User versucht, ein Pfui-Bild hochzuladen und direkt eine Meldung ausgeben.

Achja.. Ich hab zwar null Schimmer von PHP, aber vielleicht ist das für den Hash Wert ja was: http://www.phpfreaks.com/phpmanual/page/function.md5-file.html
Das ist halt der zur Datenübertragungsfunktion. Sobald jemand das Bild neu codiert, ändert der sich natürlich. Mir fiele aber sonst auch kein Weg ein, denn das geht dann schon in Richtung Bilderkennung und Signalverarbeitung. Und das ist schon Eingemachtes.
 
Zurück
Oben Unten