[Dresden-pm] Re: Bilder in Datenbank schreiben bzw. daraus lesen

Steffen Schwigon schwigon at webit.de
Don Jan 13 05:50:41 PST 2005


Johannes Studt <dresden-pm at demofreak.de> writes:
> Konkret stelle ich mir das so vor, dass ich z.B. zwei Fkt.
> put_imgdata_to_db() und get_imgdata_from_db() habe, damit ich dann
> einfach stumpf print get_imgdata_from_db($dbh, $artno); schreiben kann
> (im HTML-Code stünde etwas wie <img src=/cgi-bin/img.pl?bild01>).

IMHO isses egal, ob in DB oder Filesystem.

Wenn die Bilder klein sind (weil's ja auch nur ein kleiner Webshop
ist :-), dann spricht nix dagegen, das Zeug in der DB zu verwalten.

Man baut sich dann noch einen Cache ein, damit man sich nicht mit der
DB totkommuniziert, siehe Cache::*-Module auf CPAN.

Einer richtigen DB sollte das auch nix ausmachen. Am Ende liegt's ja
immer auf der Platte. Mit bissel Glück liest und schreibt es die DB
sogar effizienter als ein Filesystem.

Die Bilder selber auf die Platte legen, ist aber auch ok. Man
speichert sie mit Dateinamen oder Verzeichnisnamen, der gleichzeitig
einer ID in der DB entspricht und hebt sich alle Metainfos (Name, Typ,
Pfad, Größe) in der DB auf.

Muß man beim Backup'en halt an mehr Sachen denken, als nur die DB.

Für Filesystem hab' ich auch paar Zeilen Code da, zwar ohne
Projektzusammenhang sinnlos, zur Inspiration hier aber trotzdem.

Aber wenn Du genau hinguckst, isses nur trivialer
Stringzusammensetz-Kram.  Die Funktion "tempdir" zur Erzeugung
von unique IDs zu verwenden ist vielleicht ganz interessant.

Und es enthält einen Workaround gegen krankes IE-Upload-Verhalten. Der
schickt nämlich den kompletten Windoze-Pfad mit.


-------------------------------------------------------------

### ... 
use File::Temp qw( tempfile tempdir );
### ...

sub image_upload {
  my $self = shift;

  ###
  ### ... paar Sachen vorher, Parameter vom Apache-Request u.ä.
  ###

  # untaint stuff, needed in Perl's taint-mode
  $ENV{PATH} = '/bin:/usr/bin';
  delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

  my $upload     = $self->r->upload ('filename');
  my $filehandle = $upload->fh;
  my $tempname   = $upload->tempname;
  my $filename   = $upload->filename;
  my $filesize   = $upload->size;

  # only part after last pathmarker, needed for some windoze-IEs
  if ($filename =~ /[\/\\]/) {
    $filename = (split /[\/\\]/, $filename)[-1];
  }
  # untaint, needed in Perl's taint-mode
  $filename =~ s/[<>|\/\'\"&\#\`\%]/_/g;
  $filename =~ s/[[:cntrl:]]//g;
  $filename = "$1" if $filename =~ /^(.*)$/;
  return 0 unless $filename;

  # create unique dir via tempdir without cleanup
  my $tempdir = tempdir
   (
    $PATH_TO_IMAGEARCHIVE.'/XXXXXXXX',
    CLEANUP => 0
   );
  my $id = `/usr/bin/basename '$tempdir'`; ### tmpdir wird ID in DB
  chomp $id;

  # copy uploaded tempfile to final destination
  my $cmd = "/bin/cp '$tempname' '$tempdir/$filename'";
  my $ret = system($cmd);
  return 0 if $ret != 0;

  $self->create_db_entry
   ({
     id             => $id,
     filename       => $filename,
     filesize       => $filesize,
     submitdate     => scalar localtime(),
    });
  return 1;
}

-------------------------------------------------------------


Steffen
-- 
Steffen Schwigon <schwigon at webit.de>
Dresden Perl Mongers <http://dresden-pm.org/>