PHP Tracklist - Anzahl der Tracks begrenzen

Zneaf

Erfahrenes Mitglied
Hallöchen zusammen ;)

derzeit programmiere ich eine PHP - Tracklist.

Für den Fall, dass jemand nicht weiß, was das ist:
Hier kann ein DJ die Tracks die er spielt, in einer Liste auf der Website eintragen.
So kann jeder Besucher/Zuhörer nachsehen, wann welcher Track gespielt wurde.

Das ganze habe ich mit einer Datenbank gelößt.
Es gibt 2 Dateien....die erste Datei beinhaltet die Eingabemaske (nur für den DJ sichtbar), in der die Daten der Tracks eingegeben werden und die zweite Datei zeigt die eingegebenen Daten den Besuchern an.

Soweit klappt das ganze auch...es gibt nur noch ein Problem:

Ich möchte, dass maximal 50 Tracks in der Tracklist angezeigt werden.
Der älteste Track sollte dann immer überschrieben werden, wenn ein neuer eingegeben wird.

Hoffe das war einigermaßen verständlich^^

Hier der Code mit der Eingabemaske:

PHP:
<?php
if ( array_key_exists('submit', $_POST) ) {

	require_once("config2.php");
	
	$date = date("Y.m.d");
	$time = date("H:i:s");
	$author = $_POST["author"];
	$title = $_POST["title"];
	$sendung = $_POST["sendung"];
	$von = $_SESSION['username'];

// SQL-Anweisung basteln, um Daten in die DB-Tabelle einzufügen.
	if ($author == "" or $title == "" or $sendung == "") {
		echo "<hr><center><font face=\"Arial\" color=\"#333333\"><b>Bitte fülle ALLE Felder aus.</b></font></center><hr>";
	}else{
	
		require_once("config2.php");
		
		$sql = "INSERT INTO tracklist
			(
			date, time, author, title, sendung, von
			) VALUES (
			'". mysql_escape_string($date) ."',
			'". mysql_escape_string($time) ."',
			'". mysql_escape_string($author) ."',
			'". mysql_escape_string($title) ."',
			'". mysql_escape_string($sendung) ."',
			'". mysql_escape_string($von) ."'
			)";

			// SQL-Anweisung an die DB schicken und im Fehlerfall eine Meldung ausgeben.
			$res = mysql_query($sql) or exit( __LINE__.', '.__FILE__.'<br />' .mysql_error());
				
			// Wenn kein Fehler aufgetreten ist, die Tracklist aktualisieren.
			echo "<meta http-equiv='refresh' content='0; url=index.php?site=tracklist'>" ;
	}
}
?>

<!-- Eingabemaske für Tracklist -->
<form action="<?php $_SERVER['PHP_SELF']; ?>" method="post">
<table width ="500" table="0" cellspacing="0" cellpadding="2">
	<tr>
		<td><font face="Arial" color="#333333"><b>Autor: </b></font></td>
		<td><input type="text" size="30" name="author"></td>
	</tr>
	<tr>
		<td><font face="Arial" color="#333333"><b>Titel: </b></font></td>
		<td><input type="text" size="30" name="title"></font></td>
	</tr>
	<tr>
		<td><font face="Arial" color="#333333"><b>Sendung: <i>(Thema)</i></b></font></td>
		<td><input type="text" size="30" name="sendung"></font></td>
	</tr>
</table>
<br>
<table width ="500" border="0" cellspacing="0" cellpadding="2">
	<tr>
		<td><input type="submit" name="submit" value="Senden">&nbsp;<input type="reset" value="Abbrechen"></td>
	</tr>
</table>
</form>

Habt ihr vielleicht ne Idee, wie ich eine Maximal - Anzahl (50) an Tracks festlegen kann und dann bestimmen kann, dass der älteste Track immer überschrieben wird. sodass nie mehr als 50 Tracks angezeigt werden****^^

Solltet ihr noch Fragen haben, so zögert nicht, diese zu stellen :D

Vielen Dank im Voraus ;)

LG Zneaf =)
 
So auf die schnelle und ungetestet. Nach dem Insert den ältesten löschen

SQL:
DELETE
FROM tracklist
LIMIT(50,1)
 
Zuletzt bearbeitet von einem Moderator:
Hey Yaslaw ;)

erstmal vielen Dank für deine super schnelle Antwort =)

Ich hab da mal ne Frage: wo genau muss ich deinen Code einfügen und wie genau sollte das dann aussehen?
Sry bin leider bloß Hobby-Programmierer und kann mir das nicht so ganz herleiten.
Ich hab zwar das Prinzip verstanden, aber leider bin ich mir nicht so sicher, wie ich es einbauen soll.

Kommt das vielleicht noch in den programm-code des insert-befehls?

Danke im Voraus ;)

LG Zneaf ;)
 
Heyho ;)

also ich hab das jetzt mehrfach ausprobiert, aber es funktioniert einfach nicht.

Hat sonst noch jemand ne Ahnung, wie ich das am Besten anstellen könnte****

Hoffe ihr könnt mir helfen ;)

Vielen Dank

LG Zneaf
 
Hallo Zneaf..

Ich bin zwar auch kein Spezialist auf dem Gebiet, aber grundsätzlich stellt sich mir die Frage, warum du die Tracks wieder löschen willst? Vielleicht bekommst du eines Tages Lust und willst irgendwelche Auswertungen der gespielten Tracks vornehmen?

01.) unter diesem Gesichtspunkt, würde es auch ausreichen, die Ausgabe auf 50 Tracks zu limitieren.
02.) eine andere Möglichkeit wäre es, Tracks einfach nur zu deaktivieren. Dafür benötigst du aber eine zusätzliche Spalte in deiner DB. Dafür reicht ja eine spalte 'status', int (1) Not NULL, Default 1 für "aktiv" (und "2" für inaktiv)

Hat deine Tabelle auch einen Primär-Schlüssel (z.B. eine fortlaufende track_id)? Wenn nicht solltest du einen anlegen. (z.B. einen mediumint, size 8, not null). Dieser nummeriert dir automatisch die Zeilen durch, mit dem du dann besser arbeiten kannst. Außerdem umgeht dieser Key Redundanzen.

Vor dem Löschen oder Deaktivieren brauchst du meiner Ansicht nach eine einfache SQL-Abfrage die deine Primär-Schlüssel (oder die titel) zählt. SQL sowie PHP bieten dir die Funktionen MIN(), MAX(), COUNT(). Ausgehend von einer ununterbrochenen Reihenfolge deiner IDs, könntest du z.B. anschließend die zwei Variablen $differenz_id = MAX($row['track_id']) - 50; und $min_id = MIN($row['track_id']); bilden. Anschließend unterziehst du diese noch einer Prüfung... if ($min_id < $differenz_id) {

// SQL Anweisung zum Deaktivieren
$sql = "Update tracklist
SET track_status = '2'
WHERE track_id < '$differenz_id'" ;

}
else { echo 'Es mussten keine Titel deaktiviert werden.';}

Entweder lässt du diese Prüfung per Cronjob durchlaufen oder du aktivierst diesen Modus über einen zusätzlichen Button "Deaktivieren" (unter deinem Formular).

PHP:
if( isset($HTTP_POST_VARS['mode']) || isset($HTTP_GET_VARS['mode']) )
{  $mode = ( isset($HTTP_POST_VARS['mode']) ) ? $HTTP_POST_VARS['mode'] : $HTTP_GET_VARS['mode'];
   $mode = htmlspecialchars($mode);
}
else if( isset($HTTP_POST_VARS['postyourtrack']) )
{  $mode = "postyourtrack"; }
else if( isset($HTTP_POST_VARS['deaktivieren']) )
{  $mode = "deaktivieren"; }
else
{ $mode = "postyourtrack"; }

Darunter dann die zwei Modi:

PHP:
if ($mode == "postyourtrack")
{
// Dein Formularcode hier einfügen
}
if ($mode == "deaktivieren")
{
// Hier die Überprüfung und Deaktivierung der ID 
}

Dieser Ansatz ist ungeprüft und vielleicht nicht ganz perfekt, doch würde ich mich freuen, wenn er dir weiterhilft. Es mag sein, dass es andere Wege gibt... doch eine unvollkommene Antwort, sollte dich immer noch weiter bringen, als gar keine Antwort... ;)
 
Zuletzt bearbeitet:
Hey Leute ;)

@yaslaw: ich hab folgendes ausprobiert
PHP:
$sql = "INSERT INTO tracklist
			(
			date, time, author, title, sendung, von
			) VALUES (
			'". mysql_escape_string($date) ."',
			'". mysql_escape_string($time) ."',
			'". mysql_escape_string($author) ."',
			'". mysql_escape_string($title) ."',
			'". mysql_escape_string($sendung) ."',
			'". mysql_escape_string($von) ."'
			)";

			// SQL-Anweisung an die DB schicken und im Fehlerfall eine Meldung ausgeben.
			$res = mysql_query($sql) or exit( __LINE__.', '.__FILE__.'<br />' .mysql_error());

$sqldelete = "DELETE FROM tracklist LIMIT(50,1)";
$resdelete = mysql_query($sqldelete) or exit( __LINE__.', '.__FILE__.'<br />' .mysql_error());

Hat leider nur ne Fehlermeldung ausgegeben, dass irgend etwas an meiner syntax nicht stimmt =(
Aber ich glaube, dass die Art dieser Lösung generell funktioniert...hast du iwo nen Fehler entdeckt?^^
Danke für deine Hilfe =)

@Midge: Dankeschön für deinen rießen Beitrag :D Hab jetzt nicht auf Anhieb alles verstanden, aber ich lese es mir morgen nochmals durch ;)

Hoffe ihr habt noch ein paar Vorschläge :D

Vielen Dank im Voraus ;)

LG Zneaf
 
Hallo Zneaf...
Die genaue Fehlermeldung wäre schon notwendig, um dir eine präzise Antwort liefern zu können. In der Fehlermeldung steht die Zeilennummer und "near" (nahe) drin.

Vom Verdacht her, solltest du dir mal die Funktionalität von Limit genauer anschauen, denn diese enthält in der von dir verwendeten Form eine Angabe zum Bereich. Woran sollte Limit diesen Bereich definieren, wenn du scheinbar keinen primary key (Primärschlüssel) in dieser DB-Tabelle verwendest und/ oder keine WHERE Klausel definierst? So gesehen, wird Limit (meiner Ansicht nach) gar nicht herausfinden können, wo der Bereich beginnt. Außerdem hast du keine Prüfung (if-schleife) drin, die die Notwendigkeit des Löschens belegt. Was passiert z.B., wenn weniger als 50 Datensätze in deiner DB-Tabelle enthalten sind?

In der jetzigen Form sieht es so aus, als führst du die Löschanweisung pauschal bei jedem Aufruf der Seite aus. Das bedeutet, bei jedem Aufruf der Seite und nach jedem Absenden deiner Formulareingaben, wird ohne Rückfrage gelöscht****** Enthält dein Formular keine Überprüfung auf Vollständigkeit aller Eingabefelder, dann reicht es 49 mal deinen Absenden-button zu klicken und deine DB-Tabelle ist leer. :rolleyes:

Aus diesem Grund hatte ich die Überlegung in den Raum gestellt, ob du nicht lieber die Datensätze nur deaktivieren willst und dafür einen gesonderten Button verwenden möchtest!? Sekundär betrachtet, sagt es auch etwas über den Wert der Datensätze aus, wenn du diese bereits nach 50 Stück wieder löschen willst.

Bitte betrachte meine Sichtweise nicht als Kritik, sondern als simple, gut gemeinte Darstellung eines Außenstehenden, der (mit seinem begrenzten Halbwissen) nur weitere Aspekte deines Vorhabens beleuchten will. Diese Betrachtung geht eigentlich noch viel weiter... und würde bei echten Profis, auch die Frage einschließen, wer und wie kann man dein Script aufrufen? Meiner Erfahrung nach, steht das Ziel (die abschließende SQL-Anweisung) bei jedem Vorhaben ganz am Ende. Zuvor sollte die Ausführbarkeit (vor allem bei INSERT, UPDATE oder DELETE), durch die Berücksichtigung möglicher Eventualitäten (deklariert in Bedingungen) begrenzt werden.
 
Kurz bei DELETeE in der Doku nachgelesen und gesehen: Limit geht bei DELETE anderst.
Der nützt dir nicht viel.

Um die Ältesten nach 50 Einträgen zu löschen musst du zuerst mit einem SELECT diese ermitteln und dann via JOIN verknüpfen.
Wenn im SELECT der Limit höher ist als die Anazhl Daten, dann wird einfach nix ausgegeben.

SQL:
DELETE 
	test
FROM 
	test
	INNER JOIN (
					SELECT 	id
					FROM		test
					ORDER BY	id DESC
					LIMIT		50,99999
				) AS sel
		ON test.id = sel.id
 
Zuletzt bearbeitet von einem Moderator:
Hallo yaslaw ...

Alles gut und schon, mit dem INNER JOIN ... aber woher nimmt er die ID? Aus seiner Datenübergabe (aus dem Formular), geht nicht hervor, dass die Tabelle eine überhaupt eine fortlaufende ID besitzt. Daher hatte ich gestern geschrieben, dass er einen primary key braucht um damit arbeiten zu können. Alternativ, könnte er aber mit den hinterlegten Werten der DB-Spalten date und time die aktuellsten 50 Einträge herausfinden. Ein kompletter Timestamp wäre natürlich idealer gewesen.

@Zneaf

01.) Die grundlegende Frage ist also: Besitzt deine DB-Tabelle "tracklist" eine Spalte ID, die automatisch vergeben wird?
02.) Anstatt INNER JOIN könntest du eine separate sql-Abfrage verwenden, die erst einmal prüft, ob es überhaupt notwendig ist Datensätze zu löschen.
03.) Warum speicherst du Datum und Uhrzeit nicht in einem Timestamp. Dieser Timestamp benötigt nur eine Tabellenspalte und ermöglicht es trotzdem beide Angaben (Zeit und Datum) gesondert auszugeben?
 
Zurück