4

私は現在symfony1.4を使用しており、ユーザーがMicrosoftWorddocxファイルをアップロードできるようにしたいと考えています。以下のsfWidgetFormInputFileウィジェットとsfValidatorFileを使用すると、ユーザーは単純なWebフォームを使用してdocxファイルを選択して正常にアップロードできます。

$this->widgetSchema['file_name'] = new sfWidgetFormInputFile(array('label' => 'File'));

$this->validatorSchema['file_name'] = new sfValidatorFile(array(
  'required'   => true,
  'path'       => sfConfig::get('sf_upload_dir').DIRECTORY_SEPARATOR.sfConfig::get('app_dir_file_sharing').DIRECTORY_SEPARATOR,
  'mime_types' => array('application/msword',
                        'application/vnd.ms-word',
                        'application/msword',
                        'application/msword; charset=binary')
), array(
    'invalid'    => 'Invalid file.',
    'required'   => 'Select a file to upload.',
    'mime_types' => 'The file must be a supported type.'
));

問題は、ファイルがアップロードされた後、拡張子が.zipに変更され、ファイルにxmlファイルのファイルツリーが含まれることです。私の理解では、これはOffice2007がOpenxmlファイル形式を使用しているためです。symfonyまたはPHPを使用してこれが発生するのを防ぐ方法はありますか?

4

4 に答える 4

6

問題は Content-Sniffing です。新しい Office 形式は .zip ファイルであり、アップロード時にコンテンツが傍受された場合、ブラウザーはこれを ZIP ファイルとして識別し、Content-Type ヘッダーをそのように設定します。同様に、ダウンロード時に、サーバーが適切な Content-Type HTTP 応答ヘッダーを設定しない限り、ブラウザーはこれが ZIP ファイルであると想定します。

于 2010-01-20T19:51:42.063 に答える
5

Symfony 1.3+ にはsfValidatorFileのオプションがありmime_type_guessers、独自の MIME タイプゲッサー PHP callable を定義したり、ビルドインゲッサーを使用したりできます。3 つの組み込み MIME タイプ ゲッサーのいずれかを呼び出すと、docx の正しいファイル タイプが検出され、docx ファイル拡張子が保持されます。

これは、guessFromFileinfo を使用して更新されたコードです。

$this->validatorSchema['file_name'] = new sfValidatorFile(array(
'required'   => true,
'path'       => sfConfig::get('sf_upload_dir').DIRECTORY_SEPARATOR.sfConfig::get('app_dir_file_sharing').DIRECTORY_SEPARATOR,
'mime_type_guessers' => array('guessFromFileinfo'),
'mime_types' => array('application/msword',
                    'application/vnd.ms-word',
                    'application/msword',
                    'application/msword; charset=binary')
), array(
    'invalid'    => 'Invalid file.',
    'required'   => 'Select a file to upload.',
    'mime_types' => 'The file must be a supported type.'
));
于 2010-01-25T21:12:46.207 に答える
4

Symfony のファイル タイプ検出のバグのようです。回避策が記載されています。

于 2010-01-20T19:29:44.560 に答える
1

の推奨される使用法はmime_type_guessers、存在しない関数を使用しています。sfValidatorFile メソッドを使いたい場合は、 と書く必要がありますarray(array('sfValidatorFile', 'guessFromFileinfo'))。提案された解決策は、MIME タイプの検出をまったく使用せず、システムの従来の Excel 形式で問題が発生します。

sfValidatorFile クラスを拡張し、getMimeType メソッドを変更して問題を修正しました。

lib フォルダーに新しい msValidatorFile.class.php ファイルを作成します。

<?php

class msValidatorFile extends sfValidatorFile
{
  protected function getMimeType($file, $fallback)
  {
    $arrayZips = array( "application/zip", 
                        "application/x-zip", 
                        "application/x-zip-compressed");
    $officeTypes = array(
        "application/vnd.ms-word.document.macroEnabled.12",
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document", 
        "application/vnd.openxmlformats-officedocument.wordprocessingml.template", 
        "application/vnd.ms-powerpoint.template.macroEnabled.12", 
        "application/vnd.openxmlformats-officedocument.presentationml.template", 
        "application/vnd.ms-powerpoint.addin.macroEnabled.12", 
        "application/vnd.ms-powerpoint.slideshow.macroEnabled.12", 
        "application/vnd.openxmlformats-officedocument.presentationml.slideshow", 
        "application/vnd.ms-powerpoint.presentation.macroEnabled.12", 
        "application/vnd.openxmlformats-officedocument.presentationml.presentation", 
        "application/vnd.ms-excel.addin.macroEnabled.12", 
        "application/vnd.ms-excel.sheet.binary.macroEnabled.12", 
        "application/vnd.ms-excel.sheet.macroEnabled.12", 
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", 
        "application/vnd.ms-excel.template.macroEnabled.12", 
        "application/vnd.openxmlformats-officedocument.spreadsheetml.template");

    foreach ($this->getOption('mime_type_guessers') as $method)
    {
      $type = call_user_func($method, $file);

      if (null !== $type && $type !== false)
      {
        if (in_array($type, $arrayZips) && in_array($fallback, $officeTypes))
        {
           return $fallback;
        }
        return strtolower($type);
      }
    }

    return strtolower($fallback);
  }
}

フォーム コードでこの新しいバリデータを使用します。

$this->validatorSchema['file'] = 
    new msValidatorFile(array('required' => false,
                              'path' => sfConfig::get('sf_upload_dir')
                        ));
于 2013-01-16T22:28:08.420 に答える