Загрузка файла с помощью файлов PHP shredding .xls

#php #excel #mime-types #mime

#php #excel #mime-типы #mime

Вопрос:

У меня есть фрагмент кода, который принимает загруженный пользователем файл и обрабатывает его. Когда пользователь загружает файл .xls, файл измельчается. Я подозреваю, что это как-то связано с MIME, но я не слишком много знаю о них. Любая помощь будет оценена.

 <?php include ("header1.html") ?>
<!--- End --->
<tr height="100%">
    <td align="center" valign="top" style="background-image: url('images/midbg.jpg'); background-repeat:repeat-x; padding-top: 25px; " bgcolor="#e6e6e6" >

    <!--- Body begins here --->

    <table width="725"  border="0" cellspacing="0" cellpadding="2">
     <tr>
     <td width="100%" valign="top">
     <table style="margin-left:130px; margin-top:20px;">
<tr><td>
<p><strong style="font-size:12px"> </strong> </p>
<?php

$userName = $session->userName;

if ($handle = opendir('fileuploads/'.$userName)) {
    //echo "Directory handle: $handlen";
   // echo "Files:n";
    $path = 'fileuploads/'.$userName.'/';
    /* This is the correct way to loop over the directory. */
    while (false !== ($file = readdir($handle))) {
        if(($file != "Thumbs.db") amp;amp;  ($file != ".")amp;amp;  ($file != ".."))
    {
    $attachment[] = $path.$file;
    }
}
//  echo '<p><b>Current total = '.$totalsize.'K</b></p>';
closedir($handle);
} 


    function fileName($inputfile,$userName)
{
    $separator = '/'.$userName.'/';
$output = split ($separator, $inputfile);
return $output[1];
}

$files = $attachment;
//print_r($files);
// email fields: to, from, subject, and so on
 $memberEmails = $_POST['emails'];
  $bcc = $_POST['bccAddress'];

if ($bcc != '')
{
$bcc = $memberEmails . ',' . $bcc; 
}
else
{
 $bcc = $memberEmails;
}

$to = $_POST['toAddress'];
if($to != '')
{
$to = $userName. "@place.com,". $to;
}
else
{
$to = $userName. "@place.com";
}
$cc = $_POST['ccAddress'];
$from = $userName. "@place.com"; 
$subject =$_POST['subject']; 
$message = $_POST['content'];
$message = str_replace('"', '"',$message);
$headers = "From: ".$_SESSION['fullName']. "<$from>n";

// boundary 
$semi_rand = md5(time()); 
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x"; 
// headers for attachment 
if ($cc != '')
{
$headers .= "CC: ". $cc ."n";
}

if ($bcc != '')
{
$headers .= "BCC: ". $bcc ."n";
}
$headers .= "MIME-Version: 1.0n" . "Content-Type: multipart/mixed;n" . " boundary="    {$mime_boundary}""; 
// multipart boundary 
$message = "This is a multi-part message in MIME format.nn" . "--{$mime_boundary}n" . "Content-Type: text/html; charset="iso-8859-1"n" . "Content-Transfer-Encoding: 7bitnn" . $message . "nn"; 

if( count($files) > 0)
{
$message .= "--{$mime_boundary}n";
}

// preparing attachments
for($x=0;$x<count($files);$x  ){
$file = fopen($files[$x],"rb");
$data = fread($file,filesize($files[$x]));
fclose($file);
$fileName= fileName($files[$x],$userName);
$data = chunk_split(base64_encode($data));
$message .= "Content-Type: {"application/octet-stream"};n" . " name="$files[$x]"n" . 
"Content-Disposition: attachment;n" . " filename="$fileName"n" . 
"Content-Transfer-Encoding: base64nn" . $data . "nn";
$y = $x  1;
if ( count($files) > $y)
{
     $message .= "--{$mime_boundary}n";

}
}




$ok = @mail($to, $subject, $message, $headers); 


   if ($ok)
{
$logFile = "log/tmlog.log";
$logHandle = fopen($logFile, 'a');
$logData = "[" . date('Y-m-d H:i:s') . "] " .$userName. " - message sent successfully (". $to. ",".$bcc .",". $cc.")n";
fwrite($logHandle, $logData);
fclose($logHandle);
echo '<META HTTP-EQUIV="Refresh" CONTENT="0;URL=fileuploads/sendRm.php?msg=sent">';
}
else
{
$logFile = "log/tmlog.log";
$logHandle = fopen($logFile, 'a');
$logData = "[" . date('Y-m-d H:i:s') . "] " .$userName. " - message failedn";
fwrite($logHandle, $logData);
fclose($logHandle);
echo '<META HTTP-EQUIV="Refresh" CONTENT="0;URL=fileuploads/sendRm.php?msg=fail">';
}

}
?>
  

Комментарии:

1. Может быть, это я, что вы подразумеваете под измельченным?

2. Это может быть невозможно воспроизвести — отсутствует решающее определение $files . Кроме того, я не вижу ни загрузки, ни загрузки. Похоже, вы готовите электронное письмо, не получая и не отправляя загруженный файл. Тип содержимого, конечно, неправильный, его не должно быть, кроме как в кавычках или круглых скобках. Кроме того, скорее всего, вам не нужно выполнять какие-либо MIME-обработки самостоятельно при обработке загрузок на вашу веб-страницу. Вместо этого просто доступ $_FILES .

3. @Ed. О, о измельчении: какое именно измельчение происходит? Можете ли вы дать нам ссылки на измельченный и исходный файл?

4. @phihag — спасибо… Я обновлю код с некоторыми дополнительными деталями. Извините, да, я готовлю электронное письмо. Вот скриншот сравнения байтов, оригинал слева. Я не могу отправить файлы в целях безопасности. i55.tinypic.com/244wako.png

5. Вряд ли это проблема, но, пожалуйста, обратите внимание, что в спецификациях указано, что вы должны использовать rn вместо того, чтобы просто n разделять заголовки и т. Д. Большинство клиентов достаточно умны, чтобы компенсировать это, но лучше всего следовать стандартам до буквы, чтобы не было места для двусмысленности…

Ответ №1:

На каком этапе файл поврежден? На стороне сервера сразу после загрузки файла или на стороне почтового клиента, когда файл был отправлен по электронной почте?

Вот код, переписанный, чтобы сделать его доступным для чтения / совместимым со стандартами…

 $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x"; 

// headers for attachment 
if ($cc != '') $headers .= "Cc: $ccrn";    
if ($bcc != '') $headers .= "Bcc: $bccrn";
$headers .= "MIME-Version: 1.0rn"
          . "Content-Type: multipart/mixed; boundary="$mime_boundary"rn";

// multipart boundary 
$message = "This is a multi-part message in MIME format.rn"
         . "--$mime_boundaryrn"
         . "Content-Type: text/html; charset="iso-8859-1"rn"
         . "Content-Transfer-Encoding: 7bitrn"
         . "rn"
         . $message . "rn"
         . "--$mime_boundary";

if (count($files)) { // Add attachments
  for ($x = 0; $x < count($files); $x  ){
    $data = chunk_split(base64_encode(file_get_contents($files[$x])));
    $fileName = fileName($files[$x], $userName);
    $message .= "rn"
              . "Content-Type: application/octet-streamrn"
              . "Content-Disposition: attachment; filename="$fileName"rn"
              . "Content-Transfer-Encoding: base64rn"
              . "rn"
              . $data . "rn"
              . "--$mime_boundary";
  }
}

$message .= '--';
  

Комментарии:

1. Спасибо. Файл, похоже, поврежден немедленно.

2. Вы имеете в виду, как только он поступит на сервер после его загрузки? Если да, пробовали ли вы другой браузер?

3. Извините, неправильно понял ваш вопрос. Файл поврежден в электронном письме, полученном пользователями. В нем указано, что расширение типа файла было изменено (хотя оно все еще .xls), а затем отображается jibberish. Я почти уверен, что это связано с типами MIME, но понятия не имею, как подойти к диагностике этого.

4. Тип MIME не должен вызывать эту проблему, особенно при использовании application/octet-stream . Глядя на примеры сравнения байтов, которые вы опубликовали, похоже, что все вхождения байтов со значением больше 127 (7F) были заменены вопросительными знаками (3F), хотя мне пришлось бы изучить все сравнение, чтобы подтвердить это. Это наводит меня на мысль, что проблема вызвана тем, что двоичный файл интерпретируется так, как если бы он был 7-битной кодировкой (возможно, байты обрабатываются как подписанные?) Где-то по ходу строки, и это потребляет байты, которые не являются частью стандартной 128-символьной таблицы ASCII.

5. Я думаю, вы правы. Я более подробно рассмотрел два сравнения, и шаблон встречается во всем наборе. Я . "Content-Transfer-Encoding: 7bitrn" не знаю, следует ли мне использовать что-то еще?