تالار گفتمان nCIS.ir

نسخه‌ی کامل: کلاس EUP (آسان آپلود پرنس)
شما در حال مشاهده نسخه آرشیو هستید. برای مشاهده نسخه کامل کلیک کنید.
سلام دوستان وقت بخیر
مدتی پیش کلاسی برای آپلود نوشته بودم و در آن انجمن کذایی هم قرار داده بودم Big Grin
الان این کلاس رو به ورژن 1.4 ارتقا دادم که کمی در ساختار اون تغییرات ایجاد شده ، بهینه تر و سریع تر شده و در نهایت چند امکان بهش اضافه شده .

امکانات کلاس :
  • امکان آپلود به صورت تکی و چندتایی
  • امکان بررسی فرمت فایل و mimetype فایل
  • امکان ایجاد محدودیت برای حجم فایل (حداقل و حداکثر حجم فایل)
  • امکان تولید اسم تصادفی برای فایل
  • یونیکه سازی خودکار اسم فایل در صورت وجود فایل
  • خروجی آپلود به صورت آرایه همراه با ارور
موارد امنیتی آپلود رو هم داخل کلاس کاملا رعایت کردیم ، خیالتون راحت باشه  Cool

این هم کلاس :
class EUP {
	/**
	 * in the name of allah
	 * Easy Upload Prans
	 * @author Mahdi Sorkhabi
	 * @version 1.4
	 * @author website http://prans.info
	 * @author weblog http://sorkhabi.net
	 * The followings are the available columns in table 'agents':
	 * @property string $dir
	 * @property string $domin
	 * @property boolean $randomName
	 * @property integer $minSize
	 * @property integer $maxSize
	 * @property array $format
	 * @property array $log
	 * @property array $result
	 */
	private $_attributes = array(
		'dir',
		'domin',
		'randomName',
		'minSize',
		'maxSize',
		'format',
		'log' => array (),
		'result' => array(),
	);
	public function __construct ($dir,$domin,$format = array ('pdf'=> 'application/pdf'),$randomName = false,$minSize = 1024,$maxSize = 1048576)
	{
		$this->_attributes ['domin'] = $domin;
		$this->_attributes ['dir'] = $dir;
		$this->_attributes ['format'] = $format;
		$this->_attributes ['randomName'] = $randomName;
		$this->_attributes ['minSize'] = $minSize;
		$this->_attributes ['maxSize'] = $maxSize;
	}
	/**
	 * Magic Getter method
	 * @param string $fileName The name of attribute
	 *
	 * @return mixed The value of attribute
	 */
	public function __GET($fileName)
	{
		if(isset($this->_attributes)) {
			return $this->_attributes[$fileName];
		}
	}
	/**
	 * Magic setter method
	 * @param string $fileName The name of attribute
	 * @param mixed $value The value of attribute
	 */
	public function __SET($fileName, $value)
	{
		if(isset($this->_attributes)) {
			$this->_attributes[$fileName] = $value;
		}
	}
	/**
	 * Check the size
	 * @param integer $size The size to check
	 *
	 * @return boolean Whether the size is valid
	 */
	private function checkMaxSize($size)
	{
		return ($size <= $this->maxSize);
	}
	/**
	 * Check the size
	 * @param integer $size The size to check
	 *
	 * @return boolean Whether the size is valid
	 */
	private function checkMinSize($size)
	{
		return ($size >= $this->minSize);
	}
	/**
	 * Get the file extension
	 * @param string $fileName The filename
	 * @param boolean $lower Whether to return the extension in lowercase
	 *
	 * @return string The file extension
	 */
	private function getExtension($fileName)
	{
		mb_internal_encoding('utf-8');
		return mb_substr($fileName, mb_strrpos($fileName, '.') + 1);
	}
	private function checkFormat($fileName,$fileType)
	{
		$extension = $this->getExtension ($fileName);
		foreach ($this->_attributes ['format'] as $format => $MIME){
			if ($extension === $format and $fileType === $MIME){
				return true;
			}
		}
		return false;
	}
	/**
	 * Get the safe filename based on the original name
	 * @param string $fileName The original filename
	 *
	 * @return string The new filename
	 */
	private function newFileName($fileName)
	{
		$extension = '.' . $this->getExtension($fileName);
		if ($this->_attributes ['randomName']){
			return md5(rand(100000, 999999) . $fileName . rand(100000, 999999)) . $extension;
		}else{
			return str_replace('.', '-', basename($fileName,'.' . $this->getExtension ($fileName))) . $extension;
		}
	}
	/**
	 * Create a unique name
	 * @param string $fileName The original filename
	 *
	 * @return string The new filename
	 */
	private function uniqueName($fileName)
	{
		$baseName = basename($fileName,'.' . $this->getExtension ($fileName));
		$extension = '.' . $this->getExtension($fileName);
		$counter = 2;
		while(file_exists($this->dir . $fileName)) {
			$fileName = $baseName . '-' . $counter . $extension;
			$counter++;
		}
		return $fileName;
	}
	/**
	 * Add log
	 * @param string $log The log to add
	 */
	private function addLog($log)
	{
		$this->_attributes ['log'] = $log;
	}
	/**
	 * Do the real upload process
	 * @param array $element The file element (an element of $_FILES array)
	 *
	 * @return boolean|false The uploaded file URL on success, false otherwise
	 */
	private function uploadFile ($element,$key = false){
		$this->_attributes ['log'] = '';
		if ($key === false){
			list($name, $tempName, $error, $size, $mimeType) = array($element['name'], $element['tmp_name'], $element['error'], $element['size'], $element['type']);
		}else{
			list($name, $tempName, $error, $size, $mimeType) = array($element['name'][$key], $element['tmp_name'][$key], $element['error'][$key], $element['size'][$key], $element['type'][$key]);
		}
		if (trim ($name) !== '') {
			if ($error == 0) {
				if($this->checkFormat ($name,$mimeType)) {
					if($this->checkMinSize($size)) {
					   if($this->checkMaxSize($size)) {
							$newName = $this->newFileName($name);
							$newName = $this->uniqueName($newName);
							if(move_uploaded_file($tempName, $this->dir . $newName)) {
								$this->addLog ('فایل "' . $name . '" با موفقیت آپلود شد');
								$file = $this->domin . $newName;
							}
							else {
								$this->addLog('مشکلی در اجرای عملیات رخ داد (آپلود فایل "' . $name . '")');
							}
						}
						else {
							$this->addLog('سایز فایل "' . $name . '" بیش از اندازه مجاز می باشد');
						}
					}
					else{
						$this->addLog('سایز فایل "' . $name . '" کم تر از حجم مجاز می باشد');
					}
				}
				else {
					$this->addLog('پسوند فایل "' . $name . '" مجاز نیست');
				}
			}
			else{
				 $this->addLog('مشکلی در اجرای عملیات رخ داد (آپلود فایل "' . $name . '")');
			}
			if(isset ($file)){
				return array (
					'result' => true,
					'url' => $file,
					'log' => $this->_attributes ['log'],
					'fileName' => $name,
					);
			}else{
				return array (
					'result' => false,
					'url' => '',
					'log' => $this->_attributes ['log'],
					'fileName' => $name,
					);
			}
		}
		return false;
	}
	/**
	 * Execute the upload process
	 * @param array $element (an element of $_FILES array)
	 *
	 * @return array|string The upload result in single mode or an array of results in multiple mode
	 */
	public function upload($element,$multiple = false) {
		if (!is_dir ($this->_attributes ['dir'])){
			mkdir ($this->_attributes ['dir']);
		}
		if($multiple) {
			if(isset ($element ['name'])){
				$count = count ($element ['name']);
				for ($key = 0;$key < $count; $key++) {
					$result = $this->uploadFile($element,$key);
					if ($result){
						$this->_attributes ['result'][$key] = $result;
					}
				}
				return $this->_attributes ['result'];
			}
		}else{
			$result = $this->uploadFile($element,false);
			if ($result){
					$this->_attributes ['result'][0] = $result;
			}
			return $this->_attributes ['result'];
		}
	}
	public function checkUpload ($uploadResult){
		return (isset ($uploadResult ['0']) ? true : false);
	}
}
?>

نمونه کد برای آپلود به صورت تکی :
<?php
if(isset ($_POST ['one_ok'])){
	$eup = new EUP ('test/','http://site.com/test/');
	$result = $eup->upload ($_FILES ['one']);
	// نمایش فایل های آپلود شده
	if ($eup->checkUpload ($result)){
		if ($result [0]['result']){
			echo $result [0]['log'] . '<br />آدرس فایل : <br />'.$result [0]['url'];
		}else{
			echo $re ['log'] . '<br />';
		}
	}
}
?>
<meta charset="UTF-8">
<body dir="rtl">
<form method="post" enctype="multipart/form-data">
	<table>
			<tr><td>فایل :</td><td><input type="file" name="one"></td></tr></tr>
	
			<tr><td></td><td><input type="submit" name="one_ok" value="آپلود بفرما !!!"></td></tr></tr>
	</table>
</form>
</body>

نمونه کد برای آپلود چند تایی :
<?php
if(isset ($_POST ['multi_ok'])){
	$eup = new EUP ('test/','http://site.com/test/');
	$result = $eup->upload ($_FILES ['multi'],true);
	// نمایش فایل های آپلود شده
	if ($eup->checkUpload ($result)){
		foreach ($result as $re){
			if ($re['result']){
				echo $re ['log'] . '<br />آدرس فایل : <br />'.$re ['url'] . '<br />';
			}else{
				echo $re ['log'] . '<br />';
			}
		}
	}
}
?>
<meta charset="UTF-8">
<body dir="rtl">
<form method="post" enctype="multipart/form-data">
	<table>
			<tr><td>فایل :</td><td><input type="file" name="multi[]"></td></tr></tr>
			<tr><td>فایل :</td><td><input type="file" name="multi[]"></td></tr></tr>
			<tr><td>فایل :</td><td><input type="file" name="multi[]"></td></tr></tr>
			<tr><td>فایل :</td><td><input type="file" name="multi[]"></td></tr></tr>
			<tr><td></td><td><input type="submit" name="multi_ok" value="آپلود بفرما !!!"></td></tr></tr>
	</table>
</form>
</body>
از جناب شهرکی برای داکیومنت سازی و مرتب سازی کد در ورژن 1.3 تشکر می نماییم !!! Dodgy
سلام. چه نیازی هستش نام دامنه در constructor وارد بشه؟!
امکان آپـلود از URL رو هم میتونید بهش اضافه کنید؟
نام دامنه برای اینکه وقتی آدرس فایل رو که بهتون تحویل میده یک آدرس درست باشه .
فرضا :
http://prans.info/upload/1.png
خب شاید بگید چرا اینو از SERVER_NAME نمیگیریم و در نهایتش DIR رو بهش اضافه نمی کنیم ؟
در بعضی موارد ممکنه آدرس اصلی فایل با آدرسی که میشه بهش دسترسی پیدا کرد متفاوت باشه .

به احتمال زیاد اضافه خواهد شد و مثل حالت فعلی امکان آپلود به صورت تکی و مولتی رو خواهد داشت !
سلام
آیا جلوگیری از آپلود شل در این کلاس بررسی شده .
به این آدرس برید
http://barnamenevis.org/showthread.php?4...8%A2%D9%86
اگه فیلمو ببینید متوجه میشید چقد راحت شل رو آپلود میکنن.
مرسی
یکی از موارد مهم امنیتی یعنی جلوگیری از آپلود شل بجای تصویر با کمک GD رعایت نشده تا اینجا که دیدم.
وقتی تایپ و فرمت بررسی بشه و تایپ و فرمت درست وارد بشه چطوری شل اجرا میشه ؟
فکر نکنم بشه شل آپلود کردن چون هم تایپ چک میشه هم فرمت پس وقتی تایپ image/png هست دیگه چیز دیگه اجرا نمیشه ...
به هر حال بررسی می کنم ...
متاسفانه به راحتی میتوان شل رو آپلود کرد ، برای رفع این مشکل چه تغییراتی باید در کلاس صورت بگیرد ؟