Home  >  Article  >  Backend Development  >  Implementing a file management system using PHP_PHP tutorial

Implementing a file management system using PHP_PHP tutorial

WBOY
WBOYOriginal
2016-07-13 10:22:551074browse

Using PHP to implement file management system

 

 /**

 * @]Class Name[= IO

 * @]Class URI[= System.IO

* @]Purpose[=

* This class is used to process the file system

* @]Author[= SNakeVil <51JS,BU,PHPx> (snakevil@qq.com)

 * @]Version[= 1.1.1

 * @]Create[= 17:13 2004-3-25

 * @]Modifications[=

 * 4:04 2004-3-30 "

 * + Fix some bugs in generate_path() method

 * + Redesign method no_comment()

 * 4:32 2004-3-29

 * + Simplified method list_dir() return value [

 * + Add method file_info() to obtain file or directory information

 * 5:35 2004-3-28

 * + Organizing optimization algorithm

 * 7:31 2004-3-27

 * + Abstract error handling into base class pB

 * + Add method no_comment() to delete C specification comments in the file

* @]See[=

*/

class IO extends SnkClass

 var $result; //The operation returns the result. If the method return value is mixed, the successful operation result can be obtained here

 var $exec_cmd; // Execution method, currently not applied to

 var $exist_dir; // The last directory that existed when the directory was created, now used for copy() and move()

 var $buffer_size; //The size of the file reading buffer can be modified according to the service application scale and server configuration. The default value is recommended

Function IO()

parent::SnkClass();

 $this->result = array();

$this->exec_cmd = "";

$this->exist_dir = "";

$this->buffer_size = 8192;

return $this;

 }

 /**

 * @]Method Name[= list_dir()

* @]Purpose[=

* Read the contents of the specified directory and return the content array

 * @]Parameter[=

* string $dir_path specifies the directory path, the default is the current directory

 * @]Return[= mixed Returns FALSE on error, otherwise returns

 * array(

* array("name","location","type"),

 *......

 * )

* @]Author[= SNakeVil <51JS,BU,PHPx> (snakevil@qq.com)

* @]See[=

*/

Function list_dir($path=".")

 if (!is_dir($path)) return $this->error_occur(0x000B, __FUNCTION__);

 if (!is_readable($path)) return $this->error_occur(0x0002, $path);

$dh = @opendir($path);

 $result = array();

 $path = realpath($path);

 if ($path[strlen($path)-1]!=DIRECTORY_SEPARATOR) $path .= DIRECTORY_SEPARATOR; // Ensure the absolute address of the directory is followed by the directory separator

 while (FALSE!==($fh=readdir($dh))) { // Use !== to prevent files and directories with names 0 or FALSE from being processed

 if ($fh=="."||$fh=="..") continue; // Ignore system specific folders

 $i = $path.$fh; // Get the absolute address

 $t = array(

 "name" => $fh, V u,

 "location" => $i,

 "type" => is_file($i) ? 1 : (is_dir($i) ? 0 : -1)

 );

 $result[] = $t;

 }

closedir($dh);

unset($dh, $fh, $t, $i);

Clearstatcache(); // Clear file system cache

return $this->result = $result;

 }

 /**

 * @]Method Name[= file_info()

* @]Purpose[=

* Get the attributes of the specified file or directory

 * @]Parameter[=

* string $dir_path specifies the directory path, the default is the current directory

 * @]Return[= mixed Returns FALSE on error, otherwise returns

* array("name","location","type","size","access","change","modify","read","write"),

* @]Author[= SNakeVil <51JS,BU,PHPx> (snakevil@qq.com)

* @]See[=

*/

Function file_info($path=".")

 $path = realpath($path);

 if (!$path) return $this->error_occur(0x000A, __FUNCTION__);

 $result = array(

 "name" => substr($path, strrpos($path, DIRECTORY_SEPARATOR)+1),

 "location" => $path, FHH C,~|5

 "type" => is_file($path) ? 1 : (is_dir($path) ? 0 : -1),

 "size" => filesize($path),

 "access" => fileatime($path),

 "modify" => filemtime($path),

 "change" => filectime($path),

 "read" => is_readable($path),

 "write" => is_writeable($path)

 );

clearstatcache();

return $this->result = $result;

 }

 /**

 * @]Method Name[= seek file()

* @]Purpose[=

* Based on regular expression conditions, search for matching files and directories in the corresponding directory and subdirectories at a given level

 * @]Parameter[=

* string $pattern is compatible with the PERL standard regular expression to specify the search matching requirements. /^ $/ will be added, and the default is .*

* string $path Directory path to search, default is the current path

 * enum $seesk_type has three possible values ​​-1 0 1, 0 only folders, 1 only files, -1 includes both, the default is 1

* int $sub_dir Search subdirectory depth, the specified directory does not count, it is recommended not to exceed 5, the default is

* limit $limit search result limit to avoid excessive waste of system resources, the default is 100

* @]Return[= mixed Returns FALSE on error, otherwise

 * array(

 * array(

* "name","locate","type"

 * ),

 *......

 * )

* @]Author[= SNakeVil <51JS,BU,PHPx> (snakevil@qq.com)

* @]See[=

*/

Function seek_file($pattern=".*", $path=".", $seek_type=1, $sub_dir_level=0, $limit=100)

 /* Check parameter value */

$is_error = $seek_type!=1 && $seek_type!=0 && $seek_type!=-1;

 $is_error = $is_error && (!is_int($sub_dir_level) || $sub_dir_level < 0);

 $is_error = $is_error && (!is_int($limit) || $limit < 1);

 if ($is_error) return $this->error_occur(0x000B, __FUNCTION__);

unset($is_error);

 $result = array();

 /* array() == FALSE, so you need to use === */

 if (FALSE===$i=$this->list_dir($path)) return FALSE; // If the directory cannot be listed, return

for ($j=0,$k=count($i);$j<$k;$j++) {

 if ($i[$j]["type"]==-1) continue; // For non-directory and non-file items, skip

 if ($i[$j]["type"]==0&&$sub_dir_level) { // If you need to search the lower directory

 if (FALSE===$l=$this->seek_file($pattern,$i[$j]["location"],$seek_type,($sub_dir_level - 1),$limit)) return FALSE ;

 $result = array_merge($result, $l); // Add the lower directory search results

 }

 if ($seek_type+$i[$j]["type"]==1||!preg_match("/^".$pattern."$/", $i[$j]["name"] )) continue; // If the current type is not searched, skip

 $result[] = $i[$j];

 if (count($result)>=$limit) { //Truncate the length exceeding the requirement and leave the list

array_splice($result, $limit);

break;

 }

 }

unset($i, $j, $k, $l);

return $this->result = $result;

 }

 /**

 * @]Method Name[= delete()

* @]Purpose[=

* Delete the specified object, file or folder - including non-empty folders containing subdirectories and files

 * @]Parameter[=

* string $path specifies the content path to be deleted, either a file or directory

* @]Return[= boolean returns FALSE on error, otherwise TRUE

* @]Author[= SNakeVil <51JS,BU,PHPx> (snakevil@qq.com)

* @]See[=

*/

Function delete($path="") {

 $path = realpath($path);

 if (!$path) return $this->error_occur(0x000A, __FUNCTION__);

 if (!is_dir($path)) {

 if (@unlink($path)) return TRUE; // File deleted successfully

return $this->error_occur(0x0004, $path);

 } else {

 if (FALSE===$i=$this->list_dir($path)) return FALSE; // Cannot list directories

for ($j=0,$k=count($i);$j<$k;$j++)

 if (!$this->delete($i[$j]["location"])) return FALSE; // Error in deleting directory content

unset($i, $j, $k);

return TRUE;

 }

 }

 /**

 * @]Method Name[= generate_path() =l

* @]Purpose[=

* Get the absolute address of existing or non-existing files and directories

 * @]Parameter[=

* string $path The file and directory whose address you want to obtain are relative and absolute addresses

* @]Return[= string obtained address

* @]Author[= SNakeVil <51JS,BU,PHPx> (snakevil@qq.com)

* @]See[=

*/

Function generate_path($path="") {

 $i = "/"==DIRECTORY_SEPARATOR ? "\" : "/"; // Unified directory separator

$path = str_replace($i, DIRECTORY_SEPARATOR, strval($path));

 if ($path[strlen($path)-1]!=DIRECTORY_SEPARATOR) $path .= DIRECTORY_SEPARATOR;

 $i = strpos($path, DIRECTORY_SEPARATOR); // Get the position of the first directory separator in the path

 $ext = substr($path, $i+1);

 $path = substr($path, 0, $i+1);

 if ($i=realpath($path)) $path = $i; // Get the basic path

else {

 $ext = $path.$ext;

$path = realpath(".");

 }

 if (strlen($ext)) { // Process the remaining content

 $ext = preg_replace("/[:*?"<>|]/", "", explode(DIRECTORY_SEPARATOR, $ext));

array_pop($ext);

 $path = explode(DIRECTORY_SEPARATOR, $path); // Create directory layer axis

 if ($path[count($path)-1]=="") array_pop($path);

while (count($ext)) {

 $i = array_shift($ext);

 if ($i==".."&&count($path)>1) array_pop($path);

elseif (""!=str_replace(".", "", $i)) $path[] = $i;

 }

$path = implode(DIRECTORY_SEPARATOR, $path);

 }

unset($ext, $i);

return $path;

 }

 /**

* @]Method Name[= make_dir()

* @]Purpose[=

* Create any folder, either relative or absolute path, or deep creation

 * @]Parameter[=

* string $path The final directory path to be created

* @]Return[= boolean returns FALSE on error, otherwise TRUE

* @]Author[= SNakeVil <51JS,BU,PHPx> (snakevil@qq.com)

* @]See[=

*/ )

Function make_dir($path="") {

 $i = explode(DIRECTORY_SEPARATOR, $this->generate_path($path)); // Generate directory path

 $path = array_shift($i);

for ($j=0,$k=count($i);$j<$k;$j++) {

 $path .= DIRECTORY_SEPARATOR.$i[$j];

 if (!is_dir($path)) {

 if ($this->exist_dir=="") $this->exist_dir = $path; // Record the last existing directory path

 if (!@mkdir($path)) return $this->error_occur(0x0003, substr($path, 0, strrpos($path, DIRECTORY_SEPARATOR))));

 }

 }

 if ($this->exist_dir=="") $this->exist_dir = $path;

return TRUE;

 }

 /**

* @]Method Name[= verify_file()

* @]Purpose[=

 * Use MD5 algorithm to compare whether two files are the same

 * @]Parameter[=

* string $src source file path

* string $dst target file path

 * boolean $internal For files larger than 1MB, set FALSE to omit the MD5 verification step and reduce the load on the server

* @]Return[= boolean returns FALSE on error, otherwise TRUE

* @]Author[= SNakeVil <51JS,BU,PHPx> (snakevil@qq.com)

* @]See[=

*/

Function verify_file($src="", $dst="", $internal=TRUE) {

 if (!is_file($src)||!is_file($dst)) return $this->error_occur(0x000B, __FUNCTION__);

 if (!is_readable($src)) return $this->error_occur(0x0006, $src);

 if (!is_readable($dst)) return $this->error_occur(0x0006, $dst);

 $i = filesize($src);

 if (filesize($dst)!=$i) { // File sizes vary

unset($i);

return FALSE;

 }

 if ($i>1024*1024*1024&&!$internal) { // For 1MB files, if precise checking is not required, skip

unset($i);

return TRUE;

 }

unset($i);

 if (md5_file($src)!=md5_file($dst)) return FALSE; // The file MD5 validation is not met and the content is different

return TRUE;

 }

 /**

 * @]Method Name[= copy()

* @]Purpose[=

* Copy any folder or file, either relative or absolute path. After the file is copied, it will be verified to check if there are any errors or data errors

 * @]Parameter[=

* string $src_path specifies the source content path to be copied, either a file or directory

* string $dst_path specifies the target content path to be copied, which can be a file or directory. The nature is determined by $src_path, which can be the lower directory of $src_path

* @]Return[= boolean returns FALSE on error, otherwise TRUE

* @]Author[= SNakeVil <51JS,BU,PHPx> (snakevil@qq.com)

* @]See[=

*/

Function copy($src="", $dst="", $sub=FALSE) {

 if (!$src=realpath($src)) return $this->error_occur(0x000B, __FUNCTION__);

$dst = $this->generate_path($dst);

 if (is_dir($src)) { // Process directory

 /*

* Description of the algorithm:

* Originally planned to use a very simple recursive algorithm to kill gods and demons when encountering them. Later, I discovered a problem: if the target path is

* What should I do if it is a descendant path of the source path? In this way, the algorithm will continue to detect...

 * So the $this->exist_dir attribute was added to record the existing part of the target path in this case. So a new question

* The question arises: How to save this attribute?

 * Integrate the entire function into the $this->copy() method, then you must record

in this function

 * changes, so another effective method is needed to prevent its changes in each operation.

* As a workaround, I use the hidden parameter $sub. No matter what, this parameter will always be at the top of the parameter list as long as the algorithm remains unchanged

 * The latter one. Therefore, the method begins to become unstable, but there is no way to do it. We can only hope that the programmer himself will not deliberately break it.

 * When called externally, because the default is FALSE, $this->exist_dir is written. Explicit TRUE during internal recursion,

 * This attribute is guaranteed to be valid.

 */

 if (!is_readable($src)) return $this->error_occur(0x0002, $src);

 if ($dst[strlen($dst)-1]!=DIRECTORY_SEPARATOR) $dst .= DIRECTORY_SEPARATOR;

 if (TRUE===$sub&&$src==$this->exist_dir) return TRUE; // The source path is the recorded target path

 if (TRUE!==$sub) $this->exist_dir = ""; // Record the directory path that exists in the target directory path before creating the directory

 if (!$this->make_dir($dst)) return FALSE; // Create directory

 if (FALSE===$i=$this->list_dir($src)) return FALSE; // Error reading directory

 for ($j=0,$k=count($i);$j<$k;$j++) if (!$this->copy($i[$j]["location"], $dst.$i[$j]["name"],TRUE)) return FALSE;

unset($i, $j, $k);

RETURN TRUE;

 } else {

 if (!is_readable($src)) return $this->error_occur(0x0006, $src);

 if ($this->verify_file($src,$dst)) return TRUE;

 if (!copy($src,$dst)) return $this->error_occur(0x0007, $dst);

 if (!$this->verify_file($src,$dst)) {

 @unlink($dst); // Failed to copy file and delete new file

return $this->error_occur(0x0007, $dst);

 }

return TRUE;

 }

 }

 /**

 * @]Method Name[= move()

* @]Purpose[=

* Move any folder or file, either relative or absolute path. After the file move is completed, it will be verified to check whether there are any errors or data errors www.hidianying.cn

 * @]Parameter[=

* string $src_path specifies the source content path to be moved, either a file or directory

* string $dst_path specifies the target content path to be moved, which can be a file or directory. The nature is determined by $src_path, which can be the lower directory of $src_path

* @]Return[= boolean returns FALSE on error, otherwise TRUE

* @]Author[= SNakeVil <51JS,BU,PHPx> (snakevil@qq.com)

* @]See[=

*/

Function move($src="", $dst="", $sub=FALSE) {

 if (!$src=realpath($src)) return $this->error_occur(0x000B, __FUNCTION__);

$dst = $this->generate_path($dst);

 if (is_dir($src)) { // Process directory

 if (!is_readable($src)) return $this->error_occur(0x0002, $src);

 if ($dst[strlen($dst)-1]!=DIRECTORY_SEPARATOR) $dst .= DIRECTORY_SEPARATOR;

if (TRUE===$sub&&$src==$this->exist_dir) return TRUE;

 if (TRUE!==$sub) $this->exist_dir = "";

if (!$this->make_dir($dst)) return FALSE;

if (FALSE===$i=$this->list_dir($src)) return FALSE;

 for ($j=0,$k=count($i);$j<$k;$j++) if (!$this->move($i[$j]["location"], $dst.$i[$j]["name"],TRUE)) return FALSE;

unset($i, $j, $k);

if (FALSE===strpos($this->exist_dir,$src))

 if (!@rmdir($src)) return $this->error_occur(0x0004, $src); // For the upper directory of the non-target directory, delete

return TRUE;

 } else {

 if (!is_readable($src)) return $this->error_occur(0x0006, $src);

if ($this->verify_file($src,$dst)) return TRUE;

 if (!copy($src,$dst)) return $this->error_occur(0x0007, $dst);

 if (!$this->verify_file($src,$dst)) {M

 @unlink($dst);

return $this->error_occur(0x0007, $dst);

 }

 if (!@unlink($src)) return $this->error_occur(0x0006, $src); // Delete source file

return TRUE;

 }

 }

 /**

 * @]Method Name[= no_comment()

* @]Purpose[=

* Clear C specification comments in files

//This tutorial comes from the 97xxoo Tutorial Network (www.97xxoo.org). To view the complete tutorial, please click: http://www.97xxoo.org/article/1/2008/20081018053.shtml

 * @]Parameter[=

* string $path specifies the file to perform the operation

* @]Return[= boolean returns FALSE on error, otherwise TRUE

* @]Author[= SNakeVil <51JS,BU,PHPx> (snakevil@qq.com)

* @]See[=

 */

Function no_comment($path="") {

 if (!is_file($path)) return $this->error_occur(0x000B, __FUNCTION__);

 if (!is_readable($path)) return $this->error_occur(0x0006, $path);

 if (!is_writeable($path)) return $this->error_occur(0x0007, $path);

 if (!$th=tmpfile()) return $this->error_occur(0x000C, $path); // Create temporary file

 $fh = fopen($path, "r+b");

 if (!flock($fh,LOCK_EX)) { // Lock file

fclose($fh);

unset($fh);

return $this->error_occur(0x0009, $path);

 }

 $fbuffer = fread($fh, $this->buffer_size*2); // File reading buffer

 $tbuffer = ""; // Temporary file buffer<

$in_dq = $in_sq = $in_lc = $in_bc = FALSE;

 while ($fblen=strlen($fbuffer)) { // Process raw data

$fstats = feof($fh);

 for ($i=0;$i<$fblen;$i++) { // Analyze file content

 if (!$fstats&&$i+5>$fblen) break; // When the file is not completely read, the next block of file content is read when the buffer reading is completed

 $j = substr($fbuffer, $i, 2);

 $k = $j[0];

 if ($j=="/*"&&!$in_dq&&!$in_sq&&!$in_lc) { // Not in string and line comments, block comments start

 $in_bc = TRUE;

$i++;

 } elseif ($j=="*/"&&$in_bc) { // End of block comment

 $in_bc = FALSE;

$i+=2;

 } elseif ($j=="//"&&!$in_dq&&!$in_sq&&!$in_bc) { // Line comment begins

 $in_lc = TRUE;

$i++;

 } elseif ($in_lc&&($k=="r"||$k=="n")) $in_lc = FALSE; // End of line comment

elseif ($j=="\\"||$j=="\""||$j=="\'") { // escape character )

 $tbuffer .= $j;

$i++;

continue;

 } elseif ($k=="""&&!$in_sq&&!$in_bc&&!$in_lc) $in_dq = !$in_dq; // Double quote string starts and ends

elseif ($k=="'"&&!$in_dq&&!$in_bc&&!$in_lc) $in_sq = !$in_sq; // Single quote string starts and ends

 if ($in_lc||$in_bc) continue; // In comments, skip

$tbuffer .= $fbuffer[$i];

 }

 $fbuffer = substr($fbuffer, $i); // Discard the read part

unset($i, $j, $k);

 if (!$fstats) $fbuffer .= fread($fh, $this->buffer_size);

 if ($fstats||strlen($tbuffer)>=$this->buffer_size) { // Write legal data to the temporary file

 if (!fwrite($th,$tbuffer)) { // Writing failed, insufficient space

fclose($th);

flock($fh, LOCK_UN);

fclose($fh);

unset($th, $fh, $in_dq, $in_sq, $in_lc, $in_bc, $i, $j, $k);

return $this->error_occur(0x000D, "");

 }

 $tbuffer = "";

 }

 }

unset($fbuffer, $tbuffer, $fstats, $in_dq, $in_sq, $in_lc, $in_bc);

rewind($fh); // Move the file pointer back to the beginning of the file

rewind($th);

 $i = $j = "";

 $k = 0;

 while (!feof($th)) { // Write temporary file data back to the source file

 $i = fgets($th, $this->buffer_size);

 if ($j=="") { // Get the newline character of the file system

 $j= substr($i, -2);

 if ($j=="rn")

elseif ($j[1]=="r"||$j[1]=="n")

 $k = 1;

 $j = $j[1];

 } else $j = "";

 }

if (substr($i, -$k)==$j) {

 $i = rtrim(substr($i, 0, -$k), " t");

 if (strlen($i)) fwrite($fh, $i.$j); // Clear the right space

else continue;

 } else fwrite($fh, rtrim($i, " t"));

 }

 ffflush($fh); // Save and close the file

 ftruncate($fh, ftell($fh));

fclose($th);

flock($fh, LOCK_UN);

fclose($fh);

unset($i, $j, $k, $fh, $th);

return TRUE;

 }

 }

 /**

* @]Error List[=

* 0x0001 The specified directory does not exist

 * 0x0002 The specified directory does not have read permission

 * 0x0003 The specified directory does not have write permission

* 0x0004 The specified directory does not have delete permission

 * 0x0005 The specified file does not exist

 * 0x0006 The specified file does not have read permission

 * 0x0007 The specified file does not have write permission

* 0x0008 The specified file does not have delete permission

* 0x0009 The specified file cannot be locked

 * 0x000A The specified object does not exist

 * 0x000B The parameter specified by the method is incorrect

 * 0x000C Unable to create temporary file

 * 0x000D Insufficient disk space

 * 0x000E

 * 0x000F

 * 0x0010

 * 0x0011

*

 */

 ?>

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/845142.htmlTechArticleUsing PHP to implement file management system/** * @]Class Name[= IO * @]Class URI[= System.IO * @]Purpose[= * This class is used to process the file system* @]Author[= SNakeVil 51JS,BU,PHPx (snakevil@q...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn