PDA

View Full Version : آموزش: آپلود امن



abbas27
جمعه 11 اردیبهشت 1394, 14:17 عصر
اینم یه کلاس آپلود واسه دوستان.اینو خودم ننوشتم ولی عالیه.هر کدوم از دوستان تونست کلاس رو توضیح بده تا با طرز کارش هم آشنا شیم.اگه دوست داشتید لینک فیلمش رو هم بذارم.فقط هر کی میتونه توضیحاتش رو بصورت کامنت بین کدها بذاره.


UploadFile.php




<?php
namespace foundationphp;


class UploadFile
{
protected $destination;
protected $messages = array();
protected $maxSize = 51200;
protected $permittedTypes = array(
'image/jpeg',
'image/pjpeg',
'image/gif',
'image/png',
'image/webp'
);
protected $newName;
protected $typeCheckingOn = true;
protected $notTrusted = array('bin', 'cgi', 'exe', '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'];
}
}
}
?>


form.php



<?php
use foundationphp\UploadFile;


session_start();
require_once '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 = 50 * 1024;
$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="foundationphp/checkmultiple.js"></script>
</body>
</html>


checkmultiple.js



var field = document.getElementById('filename');
field.addEventListener('change', countFiles, false);


function countFiles(e) {
if (this.files != undefined) {
var elems = this.form.elements,
submitButton,
len = this.files.length,
max = document.getElementsByName('MAX_FILE_SIZE')[0].value,
maxfiles = this.getAttribute('data-maxfiles'),
maxpost = this.getAttribute('data-postmax'),
displaymax = this.getAttribute('data-displaymax'),
filesize,
toobig = [],
total = 0,
message = '';


for (var i = 0; i < elems.length; i++) {
if (elems[i].type == 'submit') {
submitButton = elems[i];
break;
}
}

for (i = 0; i < len; i++) {
filesize = this.files[i].size;
if (filesize > max) {
toobig.push(this.files[i].name);
}
total += filesize;
}
if (toobig.length > 0) {
message = 'The following file(s) are too big:\n'
+ toobig.join('\n') + '\n\n';
}
if (total > maxpost) {
message += 'The combined total exceeds ' + displaymax + '\n\n';
}
if (len > maxfiles) {
message += 'You have selected more than ' + maxfiles + ' files';
}
if (message.length > 0) {
submitButton.disabled = true;
alert(message);
} else {
submitButton.disabled = false;
}
}
}

phpdev
جمعه 11 اردیبهشت 1394, 15:16 عصر
سلام

از اینکه وقت گذاشتید ممنون و متشکر . کدش خیلی عالیه آموزشش هم مال لیندا توسط دیوید پاور هستش . دیدمش خیلی خوبه . هم ساده هم در حد خیلی بالایی کارا.

با زهم دسستون درد نکنه خداکنه همه بچه های برنامه نویس رو بیارن به سمت آموزشهای اصلی . اونوقت سطح کار برنامه نویسی تو کشور بالا میره.:لبخندساده:

abbas27
جمعه 11 اردیبهشت 1394, 15:27 عصر
خواهش میکنم.ای کاش دوستانی که تو زمینه برنامه نویسی استاد هستن بتونن آموزشهای این چنینی قرار بدن تا ما مبتدی ها راه بیفتیم.باز هم از دوستان تقاضا دارم درمورد کلاس هر توضیحی میتونن بدن.اینم لینک دانلود آموزش
http://dl.ostadsho.ir:81/programming/web/php/LcUpFlsPHP.part1.rar