Bilder aus Datenbank cachen

Das hört sich ja schonmal gut an, werds direkt morgen testen sobald ich wieder im Büro bin und Poste dann obs geklappt hat. So kommt schonmal keiner an die bildphp ran. Aber trotzdem ist das topic Problem irgendwie noch nicht gelöst.


Edit

Es muss auf jeden Fall gehen, hab gelesen das es geht, mich auch Tod gegoolt aber nichts gefunden.

wie kann ich dem Script mitteilen das er erst die bildphp aufrufen soll, wenn kein Bild, oder kein aktuelles Bild vorhanden ist? Wäre das überhaupt eine saubere Lösung?
Hier nochmal der Text der mich drauf gebracht hat:
Diesem erheblichen Nachteil gegenüber einer Verwaltung von Bildern im Dateisystem lässt sich aber mit dem selben Mitteln des Webservers begegnen. Es reicht ein Änderungszeitpunkt oder ein E-Tag zusammen mit dem Bild in der Datenbank zu speichern. Erhält der PHP-Prozess, der die Bilder ausliefert, einen Request mit "If-Modified-Since" Header, muss nur noch geprüft werden, ob das Bild sich geändert hat. Falls nicht, wird der 304-Header versendet. Dieser ganze Ablauf läßt sich in wenigen Zeilen Code realisieren und mindert diesen großen Nachteil stark..

Aber irgendwie funktioniert das noch nicht in meiner bildphp
 
Zuletzt bearbeitet:
Hey Leute, ich bins nochmal. Ersteinmal danke an sheel, jetzt ist die Datei wenigstens sicher!

Folgendes, ich bin jetzt so weit das er die Bilder aus dem Browsercache ladet, momentan geht das aber nur manuell, halt wenn ich die if anweisungen verändere. Das einzige was mir nur noch zu script fehlt ist das:
PHP:
$integerFileTime = filectime ('pfad/zur/dat.ei');
Ich weiß leider nicht wie ich den Pfad zum Bild angeben soll, bzw weiß ich nicht wie ich die letzte änderung des Bildes bekomme. Könnte mir da einer Helfen?

Das script sieht momentan so aus:
PHP:
$nid = "$_GET[id]";
	
  $result = mysql_query("SELECT image, mimetype, uploadtime FROM pics WHERE usids = $nid
	");
   $row = mysql_fetch_object($result);
    $bildalter = $row->uploadtime;
   	$dauer = 525600;//ein Jahr sollte reichen
	$exp_gmt = gmdate("D, d M Y H:i:s", $bildalter + $dauer * 60) ." GMT";
	$mod_gmt = gmdate("D, d M Y H:i:s", $bildalter) ." GMT";


$integerFileTime = filectime ('pfad/zur/dat.ei'); 
// die 1 steht hier für das bildalter aus dem browsercache, also $integerFileTime, weiß aber nicht wie ich den Pfad angeben muss
if($bildalter == 1)
 
						{header ('HTTP/1.1 304 Not Modified');
						exit;}

else{
 
					header("Content-type: $row->mimetype");
					header("Expires: " . $exp_gmt);
					header("Last-Modified: ".$mod_gmt);
					echo $row->image;
					 
}

Im Enddeffekt schaue ob Alter das Bildes( Wert aus DB) mit Alter der Header Infos übereinstimmt, wenn ja gib Not Modified aus, ansonsten lade das Bild neu und schreibe neuen Header.
 
@ the snake II, das Problem hierbei wär das jeder User ein unterschiedlichen Pfad hat und das wäre ne Unwucht an Daten...

wenn ich mir die Cache Daten ausm Firefox z.B. anschaue, steht ja im response-head das Last-Modified, welches ich definiert habe. Das einzigste was ich jetzt nur noch brauch ist das Last-Modified ausm response-head per php auszulesen um das mit dem timestamp des Bildes zu vergleichen um dann zu entscheiden ob er einen OK Header setzt, oder das Bild lädt. Aber ich weiß leider nicht wie ich mein definiertes Last-Modified auslese
 
Hi

zuerst noch mal zum 304:
Jetzt hast du mich auch zum Googlen gebracht :D
So wie in deinem Code kannst du das nicht verwenden.
Wenn der Browser das Bild noch nicht im Cache hat, verhinderst du so das Laden.

304 darf nur dann gesendet werden, wenn bei der HTTP-Anfrage
vom Browser die Erlaubnis dazu gegeben wird.
Wie man das abfragen kann, dazu gibts hier einen Beispielcode:
http://simonwillison.net/2003/apr/23/conditionalget/

Das findet heraus, ob 304 zulässig ist.
Sonst Bild übertragen.
 
ohhhh maaaaan, ich weine gleich vor Freude!
sheel 10000 fachen dank!
Dank deiner Hilfe hab ichs endlich hinbekommen!

Nur mal so nebenbei gefragt, wieso kennst dich eigentlich so gut aus? Machst das irgendwie Beruflich oder so?
 
Freut mich, dass es geht :)

Zeigst du den aktuellen Code noch einmal?
Vllt. fällt ja noch irgendein Problem auf, und für die Nachwelt ist es auch hilfreich.

Und zum Gut-auskennen...Bucher, Internet, aber am meisten Erfahrung.
Irgendwas Unbekanntes findet man immer wieder, das man lösen muss/soll/will.
Mit jedem Problem lernt man beim Lösen etwas dazu...
Ob es zum Geldverdienen, für das Forum, Eigenbenutzung oder was Anderes ist,
ist dabei ziemlich egal.
 
Klar, kann ich machen

PHP:
include $_SERVER['DOCUMENT_ROOT'].("sql.php");
$sid = mysql_real_escape_string($_GET['sid']);
$query = "	SELECT pID FROM tab WHERE spalte  = '$sid'";
					$result = mysql_query($query);
					while($row = mysql_fetch_object($result))
					{$pid = "$row->pID";} 
// gibt es keine id script beenden, ansonsten rest ausführen und ganz unten alle daten löschen
if
	(!isset($pid)){echo"fehlermeldung";
	die;}
else
{

$nid = mysql_real_escape_string($_GET[id]);
$result = mysql_query("SELECT image, mimetype, uploadtime FROM tab WHERE spa = $nid AND spb = 1
	");
	
 $row = mysql_fetch_object($result);
	$timestamp = $row->uploadtime;
 	$bild = $row->image;
	
	function doConditionalGet($timestamp) {
	$dauer = 525600;//ein Jahr sollte reichen
    // A PHP implementation of conditional get, see 
    //   http://fishbowl.pastiche.org/archives/001132.html
    $last_modified = substr(date('r', $timestamp), 0, -5).'GMT';
	$exp_gmt = gmdate("D, d M Y H:i:s", $timestamp + $dauer * 60) ." GMT";
    $etag = '"'.md5($last_modified).'"';
    // Send the headers
    header("Last-Modified: $last_modified");
	header("Expires: " . $exp_gmt);
    header("ETag: $etag");
	header("Content-type: $row->mimetype");
	//echo $row->image;
    // See if the client has provided the required headers
    $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ?
        stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) :
        false;
    $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ?
        stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : 
        false;
    if (!$if_modified_since && !$if_none_match) {
        return;
    }
    // At least one of the headers is there - check them
    if ($if_none_match && $if_none_match != $etag) {
        return; // etag is there but doesn't match
    }
    if ($if_modified_since && $if_modified_since != $last_modified) {
        return; // if-modified-since is there but doesn't match
    }
    // Nothing has changed since their last request - serve a 304 and exit
    header('HTTP/1.0 304 Not Modified');
    exit;
}

echo doConditionalGet($timestamp);
echo $bild; 

$sql ="	DELETE FROM tab
		WHERE spa  = '$sid'";
        mysql_query($sql) OR die("<pre>\n".$sql."</pre>\n".mysql_error()); 
}

Bloß hab ich noch ein klitzekleines Problem;) Nach einigen lokalen Tests ist mir aufgefallen das diese Art von Scriptschutz ganz schön auf die Perfomance geht.
Es wird praktisch folgendes gemacht nur um das Script vor Fremdzugriffen zu schützen:

-mache neuen Tabelleneintrag
-häng an den Bilderlink den Hash und die ID an
-Prüfe ob Tabelleneintrag exestiert
-wenn ja gib mimetype etc und Bild aus
-lösche Tabelleneintrag wieder

Das ist für ein einzelnes Bild ganz schön viel. Was ist jetzt wenn ich sagen wir mal 100 Bilder auf der Seite habe und 1000 Leute auf der Seite sind? Sind ziemlich viele Datenbank abfragen auf einmal.
Gibts da nicht vielleicht noch ne performantere Lösung?

LG
 
Die DB-Tabelle bleibt immer recht leer, durchsuchen dauert also nicht sonderlich lang.
Verglichen mit der Bildübertragung selbst sollte das nicht sehr ins Gewicht fallen.

Wie ist denn das bei lokalen Tests aufgefallen?
Wirklich spürbar verlangsamt?

Am Server wirkt mal der (ziemlich überall installierte) Zendserver dagegen,
der machts auch wieder etwas schneller.



Werd mir bei Gelegenheit den Code noch dirchschauen, kann aber grad nicht.
 
Naja, man merkt schon wie er erst alles überprüfen muss bevor er das Bild anzeigt. Im vergleich ohne Schutz ist das Bild fast sofort zu sehen. Vielleicht liegts auch einfach nur daran das der Rechner hier ne lahme Krücke ist. Werds auf jeden Fall bald online testen, aber erstmal muss ich alle Scripte anpassen und die Tage schaffe ich das auch nicht mehr wirklich.
LG
 

Neue Beiträge

Zurück