PHP file system basic operation class

zhaozj2021-02-16  43

/ *

*

* =========== z ==================

* QQ: 118824

* MSN: Snakevil_@hotmail.com

* Hp: http://www.snakevil.com/

* =========== z ==================

*

* /

/ **

* @] 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

* Some bugs existing in the generate_path () method

* Redesign method NO_COMMENT ()

* 4:32 2004-3-29

* Simplified method List_dir () return value

* Increase method file_info () Get file or directory information

* 5:35 2004-3-28

* Finishing optimization algorithm

* 7:31 2004-3-27

* Abstract as base class

* Increase method no_comment () Delete file in C specification notes

* @] See [=

* /

Class Io extends snkclass {

VAR $ result; // Operation returns, if the method returns value Mixed, the successful operation result can be obtained here.

Var $ exec_cmd; // Execute method, not applying it for the time being

VAR $ exist_dir; // Create the directory of the current directory, currently Copy () and Move ()

VAR $ buffer_size; // File read buffer size, according to the service application size and server configuration modification, it is recommended to default

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 specified directory content, return to the content array

* @] Parameter [=

* String $ dir_path Specifies the directory path, default is the current directory

* @] Return [= MIXED error Returns false, 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) Return $ this-> Error_occur (0x0002, $ PATH);

$ DH = @opendir ($ PATH);

$ result = array ();

$ PATH = RealPath ($ PATH);

IF ($ PATH [Strlen ($ PATH) -1]! = DIRECTORY_SEPARATOR) $ PATH. = Directory_seParetor; / / Guarantee Directory Absolute Address After Directory Separator

While (false! == ($ fH = readir ($ dh))) {// Use! == Prevent file, directory, directory, directory

IF ($ fH == "." | $ fh == "..") Continue; // ignore the system specific folder

$ I = $ PATH. $ fH; // Get absolute address

$ T = array (

"name" => $ fh,

"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 = $

}

/ **

* @] Method Name [= file_info ()

* @] Purpose [=

* Get the properties of the specified file or directory

* @] Parameter [=

* String $ dir_path Specifies the directory path, default is the current directory

* @] Return [= MIXED error Returns false, 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, STRPOS ($ PATH, DIRECTORY_SEPARATOR) 1), "location" => $ PATH,

"Type" => is_file ($ PATH)? 1: (is_dir ($ PATH)? 0: -1),

"size" => FileSize ($ PATH),

"Access" => FileAtime ($ PATH),

"Modify" => filemtime ($ PATH),

"Change" => filectime ($ PATH),

"r" => is_readable ($ PATH),

"Write" => is_writeable ($ PATH)

);

ClearsTatcache ();

Return $ this-> Result = $

}

/ **

* @] Method name [= seek_file ()

* @] Purpose [=

* Search in the corresponding directory and the subdirectory of the corresponding directory and a subdirectory of the given level in the corresponding directory, the directory

* @] Parameter [=

* String $ Pattern Compatible regular expressions indicate that the search match requires / ^ $ /, the default. *

* String $ Path for searching directory path, default is the current path

* ENUM $ SEESK_TYPE has -1 0 1 three possible values, 0 only folders, 1 file, -1 includes, default is 1

* INT $ sub_dir search for subdirectory depth, specified directory is not, it is recommended not to exceed 5, default is 0

* LIMIT $ limited to search results restriction, avoid excessive waste system resources, default is 100

* @] Return [= Mixed error Returns false, 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 the parameter value * /

$ I_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 ($ limited) || $ limited <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 you cannot list the directory, return

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

IF ($ I [$ J] ["Type"] == - 1) Continue; // Skip for non-catalog non-file items

IF ($ I [$ J] ["Type"] == 0 && $ SUB_DIR_LEVEL) {// If you need to search the underlying 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 underlying directory search result

}

IF ($ seek_type $ i [$ j] == 1 ||! preg_match ("/^"" $ Pattern. "$ /", $ i [$ j] ["name"]) Continue ; // If you do not search for the current type, skip

$ Result [] = $ i [$ j];

IF (count ($ result)> = $ limit) {// Close the length of the required length, leave the list

Array_SPLICE ($ RESULT, $ LIMIT);

Break;

}

}

UNSET ($ I, $ J, $ K, $ L);

Return $ this-> Result = $

}

/ **

* @] Method name [= delete ()

* @] Purpose [=

* Delete Specify objects, files, or folders - Non-empty folders including introns and files

* @] Parameter [=

* String $ PATH Specifies the content path, file or directory you want to delete

* @] Return [= Boolean error Returns false, 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) return true; // file deletion success

Return $ this-> Error_occur (0x0004, $ PATH);

} Else {

IF (false === $ i = $ this-> list_dir ($ PATH)) Return False; // cannot list the directory

For ($ J = 0, $ K = Count ($ i); $ J <$ K; $ J ) IF (! $ this-> Delete ($ I [$ J] ["Location"]) Return False; // Delete the contents of the directory error

UNSET ($ I, $ J, $ K);

Return True;

}

}

/ **

* @] Method name [= generate_path ()

* @] Purpose [=

* Get the absolute address of the existing or not existing files, directory

* @] Parameter [=

* String $ path To get the file file, the directory existing relative, absolute address

* @] Return [= String the address obtained

* @] Author [= snakevil <51js, bu, phpx> (snakevil@qq.com)

* @] See [=

* /

Function generate_path ($ PATH = ") {

$ I = "/" == DIRECTORY_SEPARATOR? "//": "/"; // Unified directory split

$ PATH = STR_REPLACE ($ I, Directory_separator, Strval ($ PATH));

IF ($ PATH [Strlen ($ PATH) -1]! = Directory_seParetor) $ path. = Directory_sePare;

$ I = STRPOS ($ PATH, DIRECTORY_SEPARATOR); // Get position of the first directory split in the path

$ ext = SUBSTR ($ PATH, $ I 1);

$ PATH = SUBSTR ($ PATH, 0, $ I 1);

IF ($ I = realpath) $ PATH = $ i; // Get the basic path

Else {

$ ext = $ Path. $ ext;

$ PATH = RealPath (".");

}

IF (Strlen) {// Treatment of the remaining content

$ ext = preg_replace ("/> / |] /", ",", ", explode (Directory_seParetor, $ ext));

Array_POP ($ ext);

$ PATH = EXPLODE (Directory_seParetor, $ PATH); // Set the catalog layer shaft

IF ($ Path [count ($ PATH) -1] == "" "Array_POP ($ PATH);

While (count) {

$ i = array_shift ($ ext);

IF ($ I == "." && Count> 1) Array_POP ($ PATH);

Elseif (""! = Str_replace (".", ", $ i)) $ path [] = $ i;

}

$ PATH = IMPLODE (Directory_seParetor, $ PATH);

}

UNSET ($ EXT, $ I);

Return $ PATH;

}

/ **

* @] Method name [= make_dir ()

* @] Purpose [=

* Establish any folder, the relative or absolute path, the deep construction can also

* @] Parameter [= * string $ path to create the final directory path

* @] Return [= Boolean error Returns false, otherwise TRUE

* @] Author [= snakevil <51js, bu, phpx> (snakevil@qq.com)

* @] See [=

* /

Function make_dir ($ PATH = "") {

$ i = evPlode (Directory_seParetor, $ this-> generate_path ($ PATH)); // Generate Directory Path

$ PATH = Array_shift ($ I);

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

$ PATH. = Directory_seParetor. $ 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, STRPOS ($ PATH, DIRECTORY_SEPARATOR));

}

}

IF ($ THIS-> EXIST_DIR == ") $ this-> EXIST_DIR = $ PATH;

Return True;

}

/ **

* @] Method Name [= verify_file ()

* @] Purpose [=

* Compare two files with the same MD5 algorithm

* @] Parameter [=

* String $ src source file path

* String $ DST target file path

* Boolean $ INTERAL For more than 1MB file, set False to save the MD5 inspection step, reduce server burden

* @] Return [= Boolean error Returns false, otherwise TRUE

* @] Author [= snakevil <51js, bu, phpx> (snakevil@qq.com)

* @] See [=

* /

Function Verify_File ($ SRC = ", $ dst =", $ interaal = 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 (filesis ($ dst)! = $ i) {// file size is not equal

UNSET ($ I);

Return False;

}

IF ($ I> 1024 * 1024 * 1024 &&! $ interaal) {// For 1MB file, if you do not ask for accurate check, skip

UNSET ($ I);

Return True;

}

UNSET ($ I);

IF (MD5_FILE ($ src)! = md5_file ($ dst)) Return False; // The file MD5 test does not match, and the content is different Return True;

}

/ **

* @] Method name [= Copy ()

* @] Purpose [=

* Copying, files, files, relative, or absolute paths, will be checked, check if the error data is wrong after the file replication is completed.

* @] Parameter [=

* String $ src_path Specifies the source path, file or directory you want to copy

* String $ dst_path Specifies that the target content path, file or directory you want to copy can be determined by $ src_path, which can be the next directory of $ src_path

* @] Return [= Boolean error Returns false, 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)) {// Processing Directory

/ *

* About the algorithm:

* Originally intended to use a very simple recursive algorithm, encounter God, encounter a magic, and then discovered a question: if the target path

* What should I do with the post-generation path of the source path? This way, the law will continue to detect ...

* The $ this-> EXIST_DIR property is added to record the part of the target path in this case. So the new question

* Question: How to save this property?

* Integrate the entire function to $ this-> copy () method, then you must record $ this-> exist_dir in this function.

* Changes, there is a need for an additional effective way to block changes to them in each operation.

* As a change, I use hidden parameters $ SUB, this parameter is in any case, as long as the algorithm is constant, always in the parameter table

* last one. Therefore, the method has begun to become unstable, but there is no way, you can only want the programmer to not deliberately destroy.

* Write $ this-> exist_dir when calling because of the default false. During internal recursive, dominant TRUE, no

* This property guarantees effectiveness.

* /

IF (! is_readable ($ src)) Return $ this-> Error_OCCUR (0x0002, $ SRC);

IF ($ DST [Strlen ($ DST) -1]! = Directory_seParetor) $ DST. = Directory_seParator;

IF (true === $ SUB && $ SRC == $ this-> EXIST_DIR) Return true; / / The source path is the target path of the record

IF (True! == $ SUB) $ this-> exist_dir = ""; // Record the directory path IF existing in the target directory path before the directory (! $ this-> make_dir ($ dst)) Return False; // Create a directory

IF (false === $ i = $ this-> list_dir ($ src)) Return False; // Read Directory Error

For ($ j = 0, $ k = count ($ i); $ j <$ k; $ j ) ife (! $ 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); // Copy file failed to delete new files

Return $ this-> Error_occur (0x0007, $ dst);

}

Return True;

}

}

/ **

* @] Method name [= move ()

* @] Purpose [=

* Move any folder, files, relative or absolute paths, will be paid after the file is completed, check if the error data is wrong

* @] Parameter [=

* String $ src_path Specifies the source path, file or directory you want to move.

* String $ DST_PATH Specifies the target content path, file or directory you want to move, and the nature is determined by $ src_path, which can be the next directory of $ src_path

* @] Return [= Boolean error Returns false, 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)) {// Processing Directory

IF (! is_readable ($ src)) Return $ this-> Error_OCCUR (0x0002, $ SRC);

IF ($ DST [Strlen ($ DST) -1]! = Directory_seParetor) $ 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); // Remove the upper part of the non-target directory

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);

Return $ this-> Error_occur (0x0007, $ dst);

}

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

Return True;

}

}

/ **

* @] Method Name [= no_comment ()

* @] Purpose [=

* Clear the annotation of C specification in the file

* @] Parameter [=

* String $ PATH Specifies the file to do

* @] Return [= Boolean error Returns false, otherwise TRUE

* @] Author [= snakevil <51js, bu, phpx> (snakevil@qq.com)

* @] See [=

* /

Function No_comment ($ PATH = ") {

IF (! is_file) Return $ this-> Error_occur (0x000b, __function__);

IF (! is_readable) Return $ this-> Error_occur (0x0006, $ PATH);

IF (! is_writeable) Return $ this-> Error_occur (0x0007, $ PATH);

IF (! $ th = tmpfile ()) Return $ this-> Error_occur (0x000c, $ PATH); // Create a temporary file

$ fH = fopen ($ PATH, "R B");

IF (! FLOCK ($ fh, lock_ex) {// Lock file

Fclose ($ fm);

UNSET ($ fH);

Return $ this-> Error_occur (0x0009, $ PATH);

}

$ FBUFFER = FREAD ($ FH, $ this-> buffer_size * 2); // File Read Buffer $ TBuffer = ""; // Temporary File Buffer

$ IN_DQ = $ in_sq = $ in_lc = $ in_bc = false;

While ($ FBLEN = Strlen) {// Handling Original Data

$ fstats = feof ($ fm);

For ($ I = 0; $ I <$ FBLEN; $ I ) {// Analysis File Content

If (! $ fstats && $ i 5> $ fblen) Break; / / The file is not fully read when the next buffer reading completes the next file content

$ J = Substr ($ FBUFFER, $ I, 2);

$ K = $ J [0];

IF ($ j == "/ *" &&! $ in_dq &&! $ in_sq &&! $ in_lc) {// Not in string and row bet release, block comments start

$ IN_BC = true;

$ i ;

} Elseif ($ j == "* /" && $ in_bc) {// block annotation end

$ IN_BC = false;

$ I = 2;

} Elseif ($ j == "//" &&! $ In_dq &&! $ In_sq &&! $ In_bc) {// line note begins

$ in_lc = true;

$ i ;

} Elseif ($ k == "/ r" || $ k == "/ n")) $ in_lc = false; // row comment end

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

$ TBuffer. = $ j;

$ i ;

CONTINUE;

Elseif ($ k == "" &&! $ In_sq &&! $ In_bc&&! $ In_lc) $ in_dq =! $ In_dq; // Double quotes string start, end

Elseif ($ K == "&&! $ IN_DQ &&! $ IN_BC &&! $ IN_LC) $ in_sq =! $ in_sq; // single quotes string start, end

IF ($ IN_LC || $ IN_BC) Continue; // In the comment, skip

$ TBuffer. = $ fbuffer [$ I];

}

$ FBUFFER = Substr ($ FBUFEER, $ I); // Abandoned the part

UNSET ($ I, $ J, $ K);

IF (! $ fstats) $ fbuffer. = FREAD ($ FH, $ this-> buffer_size);

IF ($ fstats || Strlen ($ TBuffer)> = $ this-> buffer_size) {// write legal data to temporary file

IF (! fwrite ($ TH, $ TBuffer)) {// Write failed, lack of space

Fclose ($ TH);

FLOCK ($ fh, lock_un);

Fclose ($ fm);

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 ($ fm); // Remift file pointer to the file

Rewind ($ TH);

$ I = $ j = "";

$ K = 0;

While (! FeOf ($ th)) {// writing temporary file data back source file

$ I = fgets ($ TH, $ THIS-> Buffer_size);

IF ($ j == ") {// get a newline system for a file system

$ J = Substr ($ I, -2);

IF ($ j == "/ r / n") $ k = 2;

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) fwrite ($ fH, $ i. $ j); // Clear the right space

Else Continue;

Else FWRITE ($ FH, RTRIM ($ I, "/ T"));

}

Fflush ($ fh); // Save, close the file

Ftruncate ($ FH, FTELL ($ FH));

Fclose ($ TH);

FLOCK ($ fh, lock_un);

Fclose ($ fm);

UNSET ($ I, $ J, $ K, $ FH, $ TH);

Return True;

}

}

/ **

* @] Error list [=

* 0x0001 Specify the directory does not exist

* 0x0002 Specify directory no reading rights

* 0x0003 Specify directory no write authority

* 0x0004 Specify directory no delete permission

* 0x0005 Specify the file does not exist

* 0x0006 Specify the file without reading rights

* 0x0007 Specify file no write authority

* 0x0008 Specify file no delete permission

* 0x0009 Specify file unable to lock

* 0x000A Specify the object does not exist

* 0x000B method specified parameter is incorrect

* 0x000c Unable to create temporary files

* 0x000D disk space is insufficient

* 0x000E

* 0x000f

* 0x0010

* 0x0011

*

* /

?>

转载请注明原文地址:https://www.9cbs.com/read-25869.html

New Post(0)