2017-05-14 20 views
0

私は助けてください、私はウェブサイトを持っており、人々はpdf、doc、xlsのようなファイルをアップロードでき、ファイルのアップロード数を制限したい。ログイン後のユーザーはアップロードページを表示してファイルをアップロードできますが、1日に3回送信した場合は、ユーザーがファイルをアップロードすることはできません。その1日に3つ以上のプロジェクトを投稿することはできません。ユーザーのファイルアップロードを制限するPHP

My files are: form.php and Uploadfile.php 


<?php 
use foundationphp\UploadFile; 

session_start(); 
require_once 'src/foundationphp/UploadFile.php'; 
if (!isset($_SESSION['maxfiles'])) { 
    $_SESSION['maxfiles'] = ini_get('max_file_uploads'); 
    $_SESSION['postmax'] = UploadFile::convertToBytes(ini_get('post_max_size')); 
    $_SESSION['displaymax'] = UploadFile::convertFromBytes($_SESSION['postmax']); 
} 
$max = 2000000; 
$result = array(); 
if (isset($_POST['upload'])) { 

    $destination = __DIR__ . '/uploaded/'; 
    try { 
     $upload = new UploadFile($destination); 
     $upload->setMaxSize($max); 
     // $upload->allowAllTypes(); 
     $upload->upload(); 
     $result = $upload->getMessages(); 
    } catch (Exception $e) { 
     $result[] = $e->getMessage(); 
    } 
} 
$error = error_get_last(); 
?> 
<!DOCTYPE HTML> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title>File Uploads</title> 
    <link href="styles/form.css" rel="stylesheet" type="text/css"> 
</head> 
<body> 
    <h1>Uploading Files</h1> 
    <?php if ($result || $error) { ?> 
    <ul class="result"> 
     <?php 
     if ($error) { 
      echo "<li>{$error['message']}</li>"; 
     } 
     if ($result) { 
      foreach ($result as $message) { 
       echo "<li>$message</li>"; 
      } 
     }?> 
    </ul> 
    <?php } ?> 
    <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post" enctype="multipart/form-data"> 
    <p> 
     <input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $max;?>"> 
     <label for="filename">Select File:</label> 
     <input type="file" name="filename[]" id="filename" multiple 
     data-maxfiles="<?php echo $_SESSION['maxfiles'];?>" 
     data-postmax="<?php echo $_SESSION['postmax'];?>" 
     data-displaymax="<?php echo $_SESSION['displaymax'];?>"> 
    </p> 
    <ul> 
     <li>Up to <?php echo $_SESSION['maxfiles'];?> files can be uploaded simultaneously.</li> 
     <li>Each file should be no more than <?php echo UploadFile::convertFromBytes($max);?>.</li> 
     <li>Combined total should not exceed <?php echo $_SESSION ['displaymax'];?>.</li> 
    </ul> 
    <p> 
     <input type="submit" name="upload" value="Upload File"> 
    </p> 
</form> 
<script src="js/checkmultiple.js"></script> 
</body> 
</html> 


And uploadfile.php 

<?php 
namespace foundationphp; 

class UploadFile 
{ 
    protected $destination; 
    protected $messages = array(); 
    protected $maxSize = 2102400;//51200; //50 KB 
    protected $permittedTypes = array(
      'image/jpeg', 
      'image/pjpeg', 
      'image/gif', 
      'image/png', 
      'image/webp', 
      'application/pdf', 
      'application/rar', 
      'application/zip', 
      'application/x-zip', 
      'application/x-zip-compressed', 
      'application/vnd.ms-excel', 
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 
      'application/msword', 
      'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 
      'application/vnd.ms-powerpoint', 
      'application/vnd.openxmlformats-officedocument.presentationml.presentation', 
      'application/vnd.oasis.opendocument.spreadsheet', 
      'application/vnd.oasis.opendocument.presentation', 
      'application/vnd.oasis.opendocument.text' 


    ); 
    protected $newName; 
    protected $typeCheckingOn = true; 
    protected $notTrusted = array('bin', 'cgi', 'exe', 'dmg', 'js', 'pl', 'php', 'py', 'sh'); 
    protected $suffix = '.upload'; 
    protected $renameDuplicates; 

    public function __construct($uploadFolder) 
    { 
     if (!is_dir($uploadFolder) || !is_writable($uploadFolder)) { 
      throw new \Exception("$uploadFolder must be a valid, writable folder."); 
     } 
     if ($uploadFolder[strlen($uploadFolder)-1] != '/') { 
      $uploadFolder .= '/'; 
     } 
     $this->destination = $uploadFolder; 
    } 

    public function setMaxSize($bytes) 
    { 
     $serverMax = self::convertToBytes(ini_get('upload_max_filesize')); 
     if ($bytes > $serverMax) { 
      throw new \Exception('Maximum size cannot exceed server limit for individual files: ' . self::convertFromBytes($serverMax)); 
     } 
     if (is_numeric($bytes) && $bytes > 0) { 
      $this->maxSize = $bytes; 
     } 
    } 

    public static function convertToBytes($val) 
    { 
     $val = trim($val); 
     $last = strtolower($val[strlen($val)-1]); 
     if (in_array($last, array('g', 'm', 'k'))){ 
      switch ($last) { 
       case 'g': 
        $val *= 1024; 
       case 'm': 
        $val *= 1024; 
       case 'k': 
        $val *= 1024; 
      } 
     } 
     return $val; 
    } 

    public static function convertFromBytes($bytes) 
    { 
     $bytes /= 1024; 
     if ($bytes > 1024) { 
      return number_format($bytes/1024, 1) . ' MB'; 
     } else { 
      return number_format($bytes, 1) . ' KB'; 
     } 
    } 

    public function allowAllTypes($suffix = null) 
    { 
     $this->typeCheckingOn = false; 
     if (!is_null($suffix)) { 
      if (strpos($suffix, '.') === 0 || $suffix == '') { 
       $this->suffix = $suffix; 
      } else { 
       $this->suffix = ".$suffix"; 
      } 
     } 
    } 

    public function upload($renameDuplicates = true) 
    { 
     $this->renameDuplicates = $renameDuplicates; 
     $uploaded = current($_FILES); 
     if (is_array($uploaded['name'])) { 
      foreach ($uploaded['name'] as $key => $value) { 
       $currentFile['name'] = $uploaded['name'][$key]; 
       $currentFile['type'] = $uploaded['type'][$key]; 
       $currentFile['tmp_name'] = $uploaded['tmp_name'][$key]; 
       $currentFile['error'] = $uploaded['error'][$key]; 
       $currentFile['size'] = $uploaded['size'][$key]; 
       if ($this->checkFile($currentFile)) { 
        $this->moveFile($currentFile); 
       } 
      } 
     } else { 
      if ($this->checkFile($uploaded)) { 
       $this->moveFile($uploaded); 
      } 
     } 
    } 

    public function getMessages() 
    { 
     return $this->messages; 
    } 

    protected function checkFile($file) 
    { 
     if ($file['error'] != 0) { 
      $this->getErrorMessage($file); 
      return false; 
     } 
     if (!$this->checkSize($file)) { 
      return false; 
     } 
     if ($this->typeCheckingOn) { 
      if (!$this->checkType($file)) { 
       return false; 
      } 
     } 
     $this->checkName($file); 
     return true; 
    } 

    protected function getErrorMessage($file) 
    { 
     switch($file['error']) { 
      case 1: 
      case 2: 
       $this->messages[] = $file['name'] . ' is too big: (max: ' . 
       self::convertFromBytes($this->maxSize) . ').'; 
       break; 
      case 3: 
       $this->messages[] = $file['name'] . ' was only partially uploaded.'; 
       break; 
      case 4: 
       $this->messages[] = 'No file submitted.'; 
       break; 
      default: 
       $this->messages[] = 'Sorry, there was a problem uploading ' . $file['name']; 
       break; 
     } 
    } 

    protected function checkSize($file) 
    { 
     if ($file['size'] == 0) { 
      $this->messages[] = $file['name'] . ' is empty.'; 
      return false; 
     } elseif ($file['size'] > $this->maxSize) { 
      $this->messages[] = $file['name'] . ' exceeds the maximum size for a file (' 
        . self::convertFromBytes($this->maxSize) . ').'; 
      return false; 
     } else { 
      return true; 
     } 
    } 

    protected function checkType($file) 
    { 
     if (in_array($file['type'], $this->permittedTypes)) { 
      return true; 
     } else { 
      $this->messages[] = $file['name'] . ' is not permitted type of file.'; 
      return false; 
     } 
    } 

    protected function checkName($file) 
    { 
     $this->newName = null; 
     $nospaces = str_replace(' ', '_', $file['name']); 
     if ($nospaces != $file['name']) { 
      $this->newName = $nospaces; 
     } 
     $nameparts = pathinfo($nospaces); 
     $extension = isset($nameparts['extension']) ? $nameparts['extension'] : ''; 
     if (!$this->typeCheckingOn && !empty($this->suffix)) { 
      if (in_array($extension, $this->notTrusted) || empty($extension)) { 
       $this->newName = $nospaces . $this->suffix; 
      } 
     } 
     if ($this->renameDuplicates) { 
      $name = isset($this->newName) ? $this->newName : $file['name']; 
      $existing = scandir($this->destination); 
      if (in_array($name, $existing)) { 
       $i = 1; 
       do { 
        $this->newName = $nameparts['filename'] . '_' . $i++; 
        if (!empty($extension)) { 
         $this->newName .= ".$extension"; 
        } 
        if (in_array($extension, $this->notTrusted)) { 
         $this->newName .= $this->suffix; 
        } 
       } while (in_array($this->newName, $existing)); 
      } 
     } 
    } 

    protected function moveFile($file) 
    { 
     $filename = isset($this->newName) ? $this->newName : $file['name']; 
     $success = move_uploaded_file($file['tmp_name'], $this->destination . $filename); 
     if ($success) { 
      $result = $file['name'] . ' was uploaded successfully'; 
      if (!is_null($this->newName)) { 
       $result .= ', and was renamed ' . $this->newName; 
      } 
      $result .= '.'; 
      $this->messages[] = $result; 
     } else { 
      $this->messages[] = 'Could not upload ' . $file['name']; 
     } 
    } 
} 
Thanks/Regards, 

Sam 
+0

ファイルの数を制限したいだけですか?またはファイルのサイズも? – treecon

+0

私はmax_file_uploads 20とpost_max_size 8Mを使用しています。これはPHPのデフォルトユーザーが20個のファイルと最大8 MBをアップロードできることです。懸念事項は、1日に3回、3回だけアップロードでき、4回目は投稿できないというメッセージです1日に3つ以上のプロジェクト。私が欲しいのは、私はユーザーが来て、アップロードするのを望んでおらず、ユーザークォータはないということです。ありがとう... – sam

+0

私はあなたにヒントを与えることができます、私はstackoverflow.comで新しい質問をしながらメッセージを受け取りました:あなたはあなたの質問の限界に達しました それはあなたが休憩が必要かもしれないように見えます - すぐにもどる! 最近2つの質問をしました。 最後の質問をしてから0日です。もう一度聞く前に7日間お待ちください。この時間を使って以前の質問を再訪し、人々がコメントで指摘した問題に対処します。 – sam

答えて

0

SQLを使用して、各ユーザーがアップロードしたファイルの量を格納できます。その後、SQLクエリーで別のファイルをアップロードできるかどうかをPHPで確認できます。

EDIT:

のは、少し詳しく説明しましょう。

a)は、サーバー・サイド:

は、これを達成するための2つの方法が存在する場合があります。

ログインフォームがあります。あなたはユーザー名とパスワードのデータベースを持っていると思いますよね?したがって、各アップロードのタイムスタンプとアップローダーのユーザー名を使用して、データベースに「アップロード」テーブルを追加できます。

PHPクラスが呼び出されるたびに、データベースにクエリを作成して、アップロード者が過去24時間以内にアップロードしたファイルの量を確認できます。数字が<ならば、PHPクラスは別のクラスをアップロードすることができます。そうでなければ、あなたのPHPクラスはあなたが望むメッセージをエコーし​​ます。

b)クライアント側。

ユーザーがファイルをアップロードするたびに、彼のアップロードに関する情報がlocalStorageに保存されます。したがって、この情報は 'アップロード'ボタンのクリックイベントでチェックされ、彼はアップロードするかどうかを許可されます。

しかし、私が言ったように、情報はHISのlocalStorageに格納されているので、このメソッドはユーザによってバイパス可能です。私はそれをお勧めしません。

+0

ありがとうtreecon、あなたは正しい、あなたの)サーバー側です。オプションが良いですあなたは私が私のデータベースに作る必要がありますどのように多くの列を教えてくださいできますか? – sam

0

は、あなたのアップロード機能を改善し、より良い再利用性とセキュリティのためUploadFileクラス内の宛先を追加します。

class UploadFile 
{ 
    protected $destination = __DIR__ . '/uploaded/'; 
    protected $messages = array(); 
    protected $maxSize = 2102400;//51200; //50 KB 
    protected $permittedTypes = array(
      'image/jpeg', 
      'image/pjpeg', 
      'image/gif', 
      'image/png', 
      'image/webp', 
      'application/pdf', 
      'application/rar', 
      'application/zip', 
      'application/x-zip', 
      'application/x-zip-compressed', 
      'application/vnd.ms-excel', 
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 
      'application/msword', 
      'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 
      'application/vnd.ms-powerpoint', 
      'application/vnd.openxmlformats-officedocument.presentationml.presentation', 
      'application/vnd.oasis.opendocument.spreadsheet', 
      'application/vnd.oasis.opendocument.presentation', 
      'application/vnd.oasis.opendocument.text' 


    ); 
    protected $newName; 
    protected $typeCheckingOn = true; 
    protected $notTrusted = array('bin', 'cgi', 'exe', 'dmg', 'js', 'pl', 'php', 'py', 'sh'); 
    protected $suffix = '.upload'; 
    protected $renameDuplicates; 

    public function __construct($uploadFolder) 
    { 
     if (!is_dir($uploadFolder) || !is_writable($uploadFolder)) { 
      throw new \Exception("$uploadFolder must be a valid, writable folder."); 
     } 
     if ($uploadFolder[strlen($uploadFolder)-1] != '/') { 
      $uploadFolder .= '/'; 
     } 
     $this->destination = $uploadFolder; 
    } 

    public function setMaxSize($bytes) 
    { 
     $serverMax = self::convertToBytes(ini_get('upload_max_filesize')); 
     if ($bytes > $serverMax) { 
      throw new \Exception('Maximum size cannot exceed server limit for individual files: ' . self::convertFromBytes($serverMax)); 
     } 
     if (is_numeric($bytes) && $bytes > 0) { 
      $this->maxSize = $bytes; 
     } 
    } 

    public static function convertToBytes($val) 
    { 
     $val = trim($val); 
     $last = strtolower($val[strlen($val)-1]); 
     if (in_array($last, array('g', 'm', 'k'))){ 
      switch ($last) { 
       case 'g': 
        $val *= 1024; 
       case 'm': 
        $val *= 1024; 
       case 'k': 
        $val *= 1024; 
      } 
     } 
     return $val; 
    } 

    public static function convertFromBytes($bytes) 
    { 
     $bytes /= 1024; 
     if ($bytes > 1024) { 
      return number_format($bytes/1024, 1) . ' MB'; 
     } else { 
      return number_format($bytes, 1) . ' KB'; 
     } 
    } 

    public function allowAllTypes($suffix = null) 
    { 
     $this->typeCheckingOn = false; 
     if (!is_null($suffix)) { 
      if (strpos($suffix, '.') === 0 || $suffix == '') { 
       $this->suffix = $suffix; 
      } else { 
       $this->suffix = ".$suffix"; 
      } 
     } 
    } 

    public function upload($renameDuplicates = true) 
    { 

$fi = new FilesystemIterator($this->destination, FilesystemIterator::SKIP_DOTS); 
$totalFiles = iterator_count($fi); 
if ($totalFiles <= 3){ 
     $this->renameDuplicates = $renameDuplicates; 
     $uploaded = current($_FILES); 
     if (is_array($uploaded['name'])) { 
      foreach ($uploaded['name'] as $key => $value) { 
       $currentFile['name'] = $uploaded['name'][$key]; 
       $currentFile['type'] = $uploaded['type'][$key]; 
       $currentFile['tmp_name'] = $uploaded['tmp_name'][$key]; 
       $currentFile['error'] = $uploaded['error'][$key]; 
       $currentFile['size'] = $uploaded['size'][$key]; 
       if ($this->checkFile($currentFile)) { 
        $this->moveFile($currentFile); 
       } 
      } 
     } else { 
      if ($this->checkFile($uploaded)) { 
       $this->moveFile($uploaded); 
      } 
     } 
} else { 
    die('You can not post more that 3 projects per day!'); //Improve this to a thrown or stuff; 
} 
    } 

    public function getMessages() 
    { 
     return $this->messages; 
    } 

    protected function checkFile($file) 
    { 
     if ($file['error'] != 0) { 
      $this->getErrorMessage($file); 
      return false; 
     } 
     if (!$this->checkSize($file)) { 
      return false; 
     } 
     if ($this->typeCheckingOn) { 
      if (!$this->checkType($file)) { 
       return false; 
      } 
     } 
     $this->checkName($file); 
     return true; 
    } 

    protected function getErrorMessage($file) 
    { 
     switch($file['error']) { 
      case 1: 
      case 2: 
       $this->messages[] = $file['name'] . ' is too big: (max: ' . 
       self::convertFromBytes($this->maxSize) . ').'; 
       break; 
      case 3: 
       $this->messages[] = $file['name'] . ' was only partially uploaded.'; 
       break; 
      case 4: 
       $this->messages[] = 'No file submitted.'; 
       break; 
      default: 
       $this->messages[] = 'Sorry, there was a problem uploading ' . $file['name']; 
       break; 
     } 
    } 

    protected function checkSize($file) 
    { 
     if ($file['size'] == 0) { 
      $this->messages[] = $file['name'] . ' is empty.'; 
      return false; 
     } elseif ($file['size'] > $this->maxSize) { 
      $this->messages[] = $file['name'] . ' exceeds the maximum size for a file (' 
        . self::convertFromBytes($this->maxSize) . ').'; 
      return false; 
     } else { 
      return true; 
     } 
    } 

    protected function checkType($file) 
    { 
     if (in_array($file['type'], $this->permittedTypes)) { 
      return true; 
     } else { 
      $this->messages[] = $file['name'] . ' is not permitted type of file.'; 
      return false; 
     } 
    } 

    protected function checkName($file) 
    { 
     $this->newName = null; 
     $nospaces = str_replace(' ', '_', $file['name']); 
     if ($nospaces != $file['name']) { 
      $this->newName = $nospaces; 
     } 
     $nameparts = pathinfo($nospaces); 
     $extension = isset($nameparts['extension']) ? $nameparts['extension'] : ''; 
     if (!$this->typeCheckingOn && !empty($this->suffix)) { 
      if (in_array($extension, $this->notTrusted) || empty($extension)) { 
       $this->newName = $nospaces . $this->suffix; 
      } 
     } 
     if ($this->renameDuplicates) { 
      $name = isset($this->newName) ? $this->newName : $file['name']; 
      $existing = scandir($this->destination); 
      if (in_array($name, $existing)) { 
       $i = 1; 
       do { 
        $this->newName = $nameparts['filename'] . '_' . $i++; 
        if (!empty($extension)) { 
         $this->newName .= ".$extension"; 
        } 
        if (in_array($extension, $this->notTrusted)) { 
         $this->newName .= $this->suffix; 
        } 
       } while (in_array($this->newName, $existing)); 
      } 
     } 
    } 

    protected function moveFile($file) 
    { 
     $filename = isset($this->newName) ? $this->newName : $file['name']; 
     $success = move_uploaded_file($file['tmp_name'], $this->destination . $filename); 
     if ($success) { 
      $result = $file['name'] . ' was uploaded successfully'; 
      if (!is_null($this->newName)) { 
       $result .= ', and was renamed ' . $this->newName; 
      } 
      $result .= '.'; 
      $this->messages[] = $result; 
     } else { 
      $this->messages[] = 'Could not upload ' . $file['name']; 
     } 
    } 
} 
+0

少し詳しく教えていただけますか、私に例を挙げてください。 – sam

+0

私のコードは機能しませんでしたか? FilesystemIteratorクラスを使用してディレクトリのファイルを数え、3以下の場合にのみ更新ルーチンを実行します。 – calexandre

0

私はあなたがあなたのDB内のユーザーテーブルを持っていると思います。新しい属性upload_day_countを追加してください... アップロードするたびに番号が3であるかどうかをチェックし、そうでない場合は、このユーザーの属性値をアップロードしてicrementできるようにします。 1日目は00h01分で、cronジョブを実行してすべてのユーザーのすべての値をリセットします。

関連する問題