2016-10-06 18 views
1

私自身の小さなプロジェクトでは、php/mysqlを使ってファイルをアップロードしてダウンロードする必要があります。phpとmysqlでアップロードされたファイルが壊れています

ファイルは次のようにPOSTを使用してフォームを介してアップロードして処理されます。

<? 
$passName1 = $_FILES['passport1']['name']; 
$tmpName1 = $_FILES['passport1']['tmp_name']; 
$fileSize1 = $_FILES['passport1']['size']; 
$fileType1 = $_FILES['passport1']['type']; 
$fp1  = fopen($tmpName1, 'r'); 
$pass_1_content = fread($fp1, filesize($tmpName1)); 
fclose($fp1); 
?> 

は、その後、私はこの機能を使用してそれらをアップロードします。

$passport1id = insert_user_file ($db, $passName1, $fileType1, $fileSize1, $pass_1_content); 

function insert_user_file ($db, $name, $type, $size, $content) { 
     try { 
      echo "<br>start insert file $name"; 
      $insertfile = new PDO("mysql:host=".$db['server'].";dbname=".$db['db'], $db['mysql_login'], $db['mysql_pass'], array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8')); 
      // set the PDO error mode to exception 
      $insertfile->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

      // prepare sql and bind parameters 
      $stmt=$insertfile->prepare ("INSERT INTO files (name, size, type, content, created) VALUES (:name, :size, :type, :content, NOW())"); 

      $stmt->bindParam(":name", $name); 
      $stmt->bindParam(":size", $size); 
      $stmt->bindParam(":type", $type); 
      $stmt->bindParam(":content", $content); 
      $stmt->execute(); 

      $file_id = $insertfile->lastInsertId(); 
      return $file_id; 
     } 
     catch(PDOException $e) { 
      echo 'error: '. $e->getMessage(); 
      return false; 
     } 
    } 

名までにaddslashes()の存在/ファイルの内容はまったく違いはありません。

get_file ($db, $_GET['id']); 

function get_file ($db, $fileid){ 
     try { 
      $get_file = new PDO("mysql:host=".$db['server'].";dbname=".$db['db'], $db['mysql_login'], $db['mysql_pass'], array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8')); 
      $get_file->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
      $file = $get_file->prepare("SELECT * FROM files where fileid=:fileid"); 
      $file->bindParam(":fileid", $fileid); 
      $file->execute(); 
      $file_data = $file->fetch(PDO::FETCH_ASSOC); 
      header('Content-Description: File Transfer'); 
      header('Content-Type: application/octet-stream'); 
      header('Content-Transfer-Encoding: binary'); 
      header('Connection: Keep-Alive'); 
      header('Expires: 0'); 
      header("Content-length: {$file_data['size']}"); 
      header("Content-type: {$file_data['type']}"); 
      header("Content-Disposition: attachment; filename={$file_data['name']}"); 
      echo $file_data['content']; 
      exit; 
     } 
     catch(PDOException $e) { 
      //echo 'error: '. $e->getMessage(); 
      return false; 
     } 
    } 
+0

'addslashes()'はまったく役に立たない。あなたはプレースホルダーで準備されたステートメントを使用しています。 DBは、(内部的に)データを安全に保つために必要なエスケープを行います。あなたがやっているのは基本的にDOUBLEエンコーディングなので、元のデータには存在しないバックスラッシュを追加しているので、データは破損しています。 –

+1

'$ pass_1_content = addslashes($ pass_1_content);'あなたは自分ですべてを破損しました – RiggsFolly

+0

そして、あなたが読んでいるファイルが "大"の場合、メモリ不足のエラーでスクリプトを強制終了する危険があります。 PHPは「値渡し」を使用しています.db関数の場合は外部のファイルを読み込み、それを関数に渡すと、そのファイルの2つのコピーがメモリ内に存在するため、RAM要件が倍増します。 –

答えて

0

私は問題を解決した: は、私は以下の機能が戻ってファイルを取得する場合、破損して表示されますが正常に動作するようです!愚かな私、混乱に終わったので、私はここに全体のコードを入れておくべきだった!

<?php 
    ob_start(); 
    session_start(); 
    require_once 'functions.php'; 

    /* 
    if(!isset($_SESSION['logged']) OR $_SESSION['logged'] == false){ 
     header ("Location: index.php"); 
     exit; 
    } 
    */ 

    //somecode here 
    //echo "logged in ok"; 
    get_file ($db, $_GET['id']); 


?> 

犯人は2行目のob_start()にあります。

Warning: Cannot modify header information - headers already sent by (output started at /sata2/home/users//functions.php:289) in /sata2/home/users//functions.php on line 130 

289これは非常に愚かな間違いです?> //some spaces were here

後にいくつかの空白を持っていた行を:これは次のように電子の警告をオーバーライド。私が逃すかもしれない警告があったかもしれないことを暗示するために@ MarkBにはありがたいです。

+1

良いキャッチ。一般的なルールとして、PHPスクリプトでは、最後の/閉じる '?>'は必要ありません。出力が必要なPHP以外のコンテンツがある場合にのみ必要です(これはあなたが持っていたものです)。 –

関連する問題