Andreas Korthaus: Zugriff auf hochgeladene Datei

Hallo!

Ich lade eine Datei mit einem HTML-Formular auf den Server an eine PHP-Script. Jetzt will ich den Pfad der temporären Datei an ein PERL-Script übergeben.
Z.B. habe ich in $_FILES stehen:

[tmp_name] => /tmp/php7FT6vd

Wie kann PERL jetzt auf die Datei zugreifen, damit ich die Datei testweise parsen kann? Ich starte das PERL-Script über system("perlscript.pl $dateiname").
Nur wo ist dieser Pfad zu finden? Ich kann den in meinem Verzeichnisbaum nicht finden. Oder muß ich die Datei dann doch irgendwo zwischenspeichern?

Viele Grüße
Andreas

  1. Hoi,

    Ich lade eine Datei mit einem HTML-Formular auf den Server an eine PHP-Script.
    Jetzt will ich den Pfad der temporären Datei an ein PERL-Script übergeben.

    Warum das denn? Warum nicht gleich Perl?

    Wie kann PERL jetzt auf die Datei zugreifen, damit ich die Datei testweise
    parsen kann? Ich starte das PERL-Script über system("perlscript.pl
    $dateiname").
    Nur wo ist dieser Pfad zu finden? Ich kann den in meinem Verzeichnisbaum nicht
    finden. Oder muß ich die Datei dann doch irgendwo zwischenspeichern?

    Du kannst ueber @ARGV auf die Kommandozeilenargumente zugreifen. Oder was meinst
    du?

    Gruesse,
     CK

    1. Hi!

      Ich lade eine Datei mit einem HTML-Formular auf den Server an eine PHP-Script.
      Jetzt will ich den Pfad der temporären Datei an ein PERL-Script übergeben.

      Warum das denn? Warum nicht gleich Perl?

      ;-)

      Weil das Script nicht nur das machen soll und ich PERL nicht gut genug kann zum einen dieses zu bewerkstelligen, und schon gar nicht den Rest den das Script noch so zu machen hat!

      Wie kann PERL jetzt auf die Datei zugreifen, damit ich die Datei testweise
      parsen kann? Ich starte das PERL-Script über system("perlscript.pl
      $dateiname").
      Nur wo ist dieser Pfad zu finden? Ich kann den in meinem Verzeichnisbaum nicht
      finden. Oder muß ich die Datei dann doch irgendwo zwischenspeichern?

      Du kannst ueber @ARGV auf die Kommandozeilenargumente zugreifen. Oder was meinst
      du?

      Das ist klar, so kann ich leicht einen Dateinamen übergeben, mache ich auch, aber das Problem ist, das ich die Datei hochlade und PHP steht die Datei meines Wissens für die Laufzeit des Scriptes in einem temporären Verzeichnis zur Verfügung und ich kann in PHP über $_FILES["filename"]["temp_name"] drauf zugreifen.
      Doch bevor ich die temporäre Datei(Excel) in eine anderes Verzeichnis kopiere, will ich überprüfen, ob es sich tatsächlich um eine Excel-Datei handelt, zu dem Zweck will  ich in PERL folgende Prüfung durchführen:

      use Spreadsheet::ParseExcel;
          my ($file) = @ARGV;
          my $path = "/weiss/ich/halt/nicht/";
          my $oExcel = new Spreadsheet::ParseExcel;
          my $oBook = $oExcel->Parse($path.$file);

      if (defined($oBook)){print "OK";}
          else {print "FEHLER";}

      Dieses Script rufe ich wie gesagt aus PHP über

      system("script.pl $filename");

      auf. Wenn die Datei normal im Filesystem erreichbar wäre, wäre es überhaupt kein Problem. Wenn ich den kompletten Pfad weiß kann ich den in PERL angeben und muß nur noch den Namen übertragen(mit @ARGV).

      Aber leider komme ich nicht an den Pfad, oder kommt da PERL definitiv nicht dran, so dass ich die Datei erst in ein eigenes temporäres Verzeichnis kopieren muß und im Fehlerfall löschen? Oder am besten direkt ins endgültige Verzeichnis und ggfs. löschen würde ich sagen. Ich will halt vermeiden das man eine andere Datei als eine Excel-Datei hochladen kann!

      Viele Grüße
      Andreas

      1. Hoi,

        Weil das Script nicht nur das machen soll und ich PERL nicht gut genug kann
        zum einen dieses zu bewerkstelligen, und schon gar nicht den Rest den das
        Script noch so zu machen hat!

        Lernen.

        Das ist klar, so kann ich leicht einen Dateinamen übergeben, mache ich auch,
        aber das Problem ist, das ich die Datei hochlade und PHP steht die Datei
        meines Wissens für die Laufzeit des Scriptes in einem temporären Verzeichnis
        zur Verfügung und ich kann in PHP über $_FILES["filename"]["temp_name"]
        drauf zugreifen.

        Richtig.

        Doch bevor ich die temporäre Datei(Excel) in eine anderes Verzeichnis
        kopiere, will ich überprüfen, ob es sich tatsächlich um eine Excel-Datei
        handelt, zu dem Zweck will  ich in PERL folgende Prüfung durchführen:

        Und wo ist das Problem?

        use Spreadsheet::ParseExcel;
            my ($file) = @ARGV;

        my $file = shift;

        oder

        my $file = $ARGV[0];

        my $path = "/weiss/ich/halt/nicht/";

        Der Path ist schon enthalten in '$file'.

        system("script.pl $filename");

        Du wist wohl Backticks benutzen muessen oder per exit(-1) den exitcode abfragen
        muessen.

        auf. Wenn die Datei normal im Filesystem erreichbar wäre, wäre es überhaupt
        kein Problem.

        Das ist sie doch. Sie wird einfach geloescht, wenn das Script zuende gelaufen
        ist. Aber das laeuft erst zuende, wenn der Perl-Prozess zuende ist.

        Wenn ich den kompletten Pfad weiß kann ich den in PERL angeben und muß nur
        noch den Namen übertragen(mit @ARGV).

        Der steht doch in $_FILES['name']['temp_name']

        Gruesse,
         CK

        1. auf. Wenn die Datei normal im Filesystem erreichbar wäre, wäre es überhaupt
          kein Problem.

          Das ist sie doch. Sie wird einfach geloescht, wenn das Script zuende gelaufen
          ist. Aber das laeuft erst zuende, wenn der Perl-Prozess zuende ist.

          Hmmm, darauf würde ich bei Unix-Systemen nicht wetten. Man kann offene Dateien löschen, sie liegen danach zwar noch auf der Platte, sind aber in keinem Verzeichnis mehr zu finden. Demo:

          #!/usr/bin/perl

          open FILE,">/tmp/blafasel" or die $!;
          print FILE "Hallo Welt";
          close FILE;

          system '/bin/ls /tmp';

          open FILE,"</tmp/blafasel" or die $!;
          unlink "/tmp/blafasel";

          jetzt existiert die Datei noch, aber ist unsichtbar!

          system '/bin/ls /tmp';
          print while <FILE>;
          close FILE;

          Siehe auch Doku zu CGI.pm, Direktive -private_tempfiles:

          CGI.pm can process uploaded file. Ordinarily it spools the uploaded file to a temporary directory, then deletes the file when done. However, this opens the risk of eavesdropping as described in the file upload section. Another CGI script author could peek at this data during the upload, even if it is confidential information. On Unix systems, the -private_tempfiles pragma will cause the temporary file to be unlinked as soon as it is opened and before any data is written into it, reducing, but not eliminating the risk of eavesdropping (there is still a potential race condition).

          Wenn PHP das auch macht, wundert es mich nicht, wenn das aus PHP heraus aufgerufene Perl-Script die Datei nicht findet.

          Alexander

        2. Hi!

          Lernen.

          Ja, mache ich ja manchmal zwischendurch, aber ich kann noch nichtmal  vernünftig PHP! Eins nach dem anderen!

          Und wo ist das Problem?

          Keine Ahnung! Ich hatte es von vornherein ausgeschlossen das es doch so einfach ist, naja, jewtzt gehts jedenfalls - übrigens mit dem originalen von mir geposteten Script!

          use Spreadsheet::ParseExcel;
              my ($file) = @ARGV;

          my $file = shift;

          oder

          my $file = $ARGV[0];

          wieso? Das hatte ich hier mal gefragt und da wurd emir die obige Variante genannet. Was ist der Unterschied/Vorteil der anderen Varianten?

          my $path = "/weiss/ich/halt/nicht/";

          Der Path ist schon enthalten in '$file'.

          Ja, ich dachte halt den müßte ich extra angeben, konte mir nicht vorstellen das der Pfad so kurz sein kann, vor allem da ich selbst über SSH auf der Verzeichnisebene gar keinen Zugriff habe!

          system("script.pl $filename");

          Du wist wohl Backticks benutzen muessen oder per exit(-1) den exitcode abfragen
          muessen.

          stimmt. War mich noch nie aufgefallen! macvhe das jetz mit shell_exec()

          auf. Wenn die Datei normal im Filesystem erreichbar wäre, wäre es überhaupt
          kein Problem.

          Das ist sie doch. Sie wird einfach geloescht, wenn das Script zuende gelaufen
          ist. Aber das laeuft erst zuende, wenn der Perl-Prozess zuende ist.

          Stimmt!

          Gibt es noch ne Möglichkeit das Script schneller zu machen? z.B. use strict rausschmeißen, oder nur einen Teil des parseExcel-Moduls einbinden, oder sonst was?

          Vielen Dank jedenfalls!

          Grüße
          Andreas