Соглашение об именовании файлов и разрешенные символы между различными ОС - PullRequest
0 голосов
/ 28 ноября 2011

Я пишу кусок кода на PHP для сохранения вложений электронной почты. Могу ли я предположить, что это никогда не даст сбой, потому что разные разрешенные символы между ОС?

foreach($message->attachments as $a)
{
   // Make dir if not exists
   $dir = __DIR__ . "/saved/$uid"; // Message id
   if (!file_exists($dir)) mkdir($dir) or die("Cannot create: $dir");

   // Save the attachment using original!!! filename as found in email
   $fp = fopen($dir . '/' . $a->filename, 'w+');
   fwrite($fp, $a->data);
   fclose($fp);
}

Ответы [ 3 ]

2 голосов
/ 28 ноября 2011

Никогда не следует использовать имя, которое вы не можете контролировать, оно может содержать всевозможные символы, например ../../...

Вы можете использовать функцию типа basename для очистки и константу типа DIRECTORY_SEPARATOR для разделения каталогов.

Лично я бы переименовал файл, но вы также можете отфильтровать переменные перед их использованием.

0 голосов
/ 18 апреля 2014

НЕТ, вы должны предполагать, что это будет с высокой вероятностью неудачи.по двум причинам:

  1. что если в 2 электронных письмах есть файлы с одинаковыми именами (например, selfie.jpg)?
  2. что если имя файла содержит недопустимые символы?

Вы должны использовать внутреннее соглашение об именах (например, user + datetime + sequential) и сохранять имена в таблице MySQL как минимум с 3 полями:

  1. Id - Autonumbered
  2. имя файла - как сохранено вашим php
  3. оригинальное имя - как в исходном электронном письме
  4. необязательное имя пользователя - или код пользователя или адрес электронной почты того, кто отправил электронное письмо
  5. необязательный штамп даты и времени

сохраните исходное имя файла как VARCHAR, и вы сможете отслеживать исходное имя и даже показывать его, искать его и т. Д.

0 голосов
/ 28 ноября 2011

рекомендуется заменить некоторые символы, которые могут встречаться в именах файлов на окнах.

Unix может обрабатывать практически любой символ в имени файла (но не "/" и 0x00 [нулевой символ]), но для предотвращения проблем кодирования и трудностей при загрузке файла я бы предложил заменить все, что не соответствует /[A-Za-Z0-9_-\.]/g, который удовлетворяет полностью переносимому формату имени файла POSIX.

так что preg_replace("/[^A-Za-Z0-9_-\.]/g","_",$filename); сделает хорошую работу.

более щедрым подходом было бы заменить только |\?*<":>+[]\x00/, который оставляет символы специального языка, такие как öäü, нетронутыми и совместим с FAT32, NTFS, любым Unix и Mac OS X.

в этом случае используйте preg_replace("/[\|\\\?\*<\":>\+\[\]\/]\x00/g","_",$filename);

...