کپی کردن فایل و فولدرهای تودرتو در PHP به روش یونیکسی

بلاگ

همانطور که می دانید PHP در مدیریت فایل ها و فولدرهای تو در تو ضعیف است و توابع زیادی برای تسهیل اینکار وجود ندارد. پس تصمیم گرفتم برای حل بخشی از این مشکل این تابع را بنویسم. فرمت استفاده از تابع بسیار شبیه کپی کردن فایل در Linux/Unix است که در نتیجه انعطاف پذیری زیادی دارد.

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

Thiago نسخه متفاوتی از این تابع را نوشته است

ظاهرا این تابع مورد توجه خیلی از برنامه نویسان PHP قرار گرفته و بعضی آن را به عنوان بهترین روش کپی کردن فایل/فولدر در PHP شناختند!

/**
* Create a new directory, and the whole path.
*
* If  the  parent  directory  does  not exists, we will create it,
* etc.
* @todo
*     - PHP5 mkdir functoin supports recursive, it should be used
* @author baldurien at club-internet dot fr 
* @param string the directory to create
* @param int the mode to apply on the directory
* @return bool return true on success, false else
* @previousNames mkdirs
*/

function makeAll($dir, $mode = 0777, $recursive = true) {
    if( is_null($dir) || $dir === "" ){
        return FALSE;
    }
    
    if( is_dir($dir) || $dir === "/" ){
        return TRUE;
    }
    if( makeAll(dirname($dir), $mode, $recursive) ){
        return mkdir($dir, $mode);
    }
    return FALSE;
}

/**
 * Copies file or folder from source to destination, it can also do
 * recursive copy by recursively creating the dest file or directory path if it wasn't exist
 * Use cases:
 * - Src:/home/test/file.txt ,Dst:/home/test/b ,Result:/home/test/b -> If source was file copy file.txt name with b as name to destination
 * - Src:/home/test/file.txt ,Dst:/home/test/b/ ,Result:/home/test/b/file.txt -> If source was file Creates b directory if does not exsits and copy file.txt into it
 * - Src:/home/test ,Dst:/home/ ,Result:/home/test/** -> If source was directory copy test directory and all of its content into dest      
 * - Src:/home/test/ ,Dst:/home/ ,Result:/home/**-> if source was direcotry copy its content to dest
 * - Src:/home/test ,Dst:/home/test2 ,Result:/home/test2/** -> if source was directoy copy it and its content to dest with test2 as name
 * - Src:/home/test/ ,Dst:/home/test2 ,Result:->/home/test2/** if source was directoy copy it and its content to dest with test2 as name
 * @todo
 *  - Should have rollback so it can undo the copy when it wasn't completely successful
 *  - It should be possible to turn off auto path creation feature f
 *  - Supporting callback function
 *  - May prevent some issues on shared enviroments : http://us3.php.net/umask
 * @param $source //file or folder
 * @param $dest ///file or folder
 * @param $options //folderPermission,filePermission
 * @return boolean
 */
function smartCopy($source, $dest, $options=array('folderPermission'=>0755,'filePermission'=>0755))
{
	$result=false;
	
	//For Cross Platform Compatibility
	if (!isset($options['noTheFirstRun'])) {
		$source=str_replace('\\','/',$source);
		$dest=str_replace('\\','/',$dest);
		$options['noTheFirstRun']=true;
	}
	
	if (is_file($source)) {
		if ($dest[strlen($dest)-1]=='/') {
			if (!file_exists($dest)) {
				makeAll($dest,$options['folderPermission'],true);
			}
			$__dest=$dest."/".basename($source);
		} else {
			$__dest=$dest;
		}
		$result=copy($source, $__dest);
		chmod($__dest,$options['filePermission']);
		
	} elseif(is_dir($source)) {
		if ($dest[strlen($dest)-1]=='/') {
			if ($source[strlen($source)-1]=='/') {
				//Copy only contents
			} else {
				//Change parent itself and its contents
				$dest=$dest.basename($source);
				@mkdir($dest);
				chmod($dest,$options['filePermission']);
			}
		} else {
			if ($source[strlen($source)-1]=='/') {
				//Copy parent directory with new name and all its content
				@mkdir($dest,$options['folderPermission']);
				chmod($dest,$options['filePermission']);
			} else {
				//Copy parent directory with new name and all its content
				@mkdir($dest,$options['folderPermission']);
				chmod($dest,$options['filePermission']);
			}
		}

		$dirHandle=opendir($source);
		while($file=readdir($dirHandle))
		{
			if($file!="." && $file!="..")
			{
				$__dest=$dest."/".$file;
				$__source=$source."/".$file;
				//echo "$__source ||| $__dest<br />";
				if ($__source!=$dest) {
					$result=smartCopy($__source, $__dest, $options);
				}
			}
		}
		closedir($dirHandle);
		
	} else {
		$result=false;
	}
	return $result;
}

امتیاز شما: خالی میانگین: 2 (14 رای)

نظرات

تصویر حمید محمدنژاد

سلام و خسته نباشید واقعا

سلام و خسته نباشید
واقعا ممنون از ارائه این کد
من در حال نوشتن یه سورس وبلاگدهی هستم ولی نمیدونم چطوری وقتی یه کاربر میخواد ثبت نام کنه یک سابدومین براش ثبت میشه ؟
با این کدی که شما نوشتید میتونم سورس رو براش نصب کنم ولی بردنش به یه سابدمین رو بلد نیستم و تو اینترنت فارسی هم نتونستم پیدا کنم البته انگلیسیم هم ضعیفه
ممکنه کمکم کنید