前言:
項目開發過程中,網站一般部署到遠程服務器,所以文件管理就不能和本機操作一樣方便。通常文件管理是用ftp下載到本地,修改后再上傳,或者遠程登錄到服務器進行修改。但是這些操作都依賴於復雜的第三方軟件。如果只是想簡單修改網站中一個頁面中的文字,或查看文件代碼,相對於繁瑣的使用第三方軟件進行操作的流程,如果有一個小程序能在線操作文件,那就能方便快速達到自己的需求了。所以,SuExplorer就是在這樣的需求中被開發出來。
秉承自己開發的小工具一貫的風格,首先是要盡可能綠色單文件,盡量不依賴其他文件,然后是容易部署。 這樣才能方便在項目中提高生產力!
簡介:
SuExplorer_PHP是一個用於在線管理文件的單文件綠色版PHP程序,和phpinfo.php一樣可以方便放到項目中使用。 開發項目過程中,操作服務器上的文件是一個費時費力的流程,如果有一個通用管理程序,可以很簡單而高效地管理服務器上的文件,那對項目的開發效率肯定有明顯的提升,可以減少很多重復而單調的體力勞動。但是,管理服務器上的文件,首先要連接上服務器,然后用第三方工具進行操作,為了簡單查看一下文件源碼,卻要安裝一大堆不需要的依賴文件,而且還要開啟和關閉第三方軟件,效率有點低。於是決定自己抽出一點時間來開發一個自己用起來順手的在線文件管理小工具,簡單而高效,用起來還順手~
特性:
1、單文件綠色版,無外部依賴,方便部署使用 2、支持登錄驗證 3、支持內置配置文件,使用更靈活 功能:
- 在線創建文件或目錄
- 在線刪除文件或目錄
- 在線重命名文件或目錄
- 在線編輯文本文件
- 在線上傳文件
- 在線壓縮
- 在線解壓縮
使用: - SuExplorer_3_1文件復制到您的項目中任意目錄(本文件為單文件綠色版,方便使用).
- 修改配置內容為適合您需要的規則.
- 運行本文件, 開始在線管理文件
項目地址:https://gitee.com/sutroon/SuExplorer_PHP_3_0
php單文件管理器:
<?php session_start(); /** * SuExplorer.php * 在線php/ini/conf/sh等腳本文件編輯器, 不依賴ftp和服務器帳號(單頁綠色文件,方便部署) * @since 1.0 <2015-5-11> SoChishun <14507247@qq.com> Added. * @since 2.0 <2015-7-24> SoChishun * 1.重命名為SuExplorer.php * 2.改進若干外觀樣式 * 3.新增登錄驗證模塊 * 4.新增刪除功能 * @since 3.0 <2015-10-7> SoChishun * 1.新增在線壓縮和解壓功能 * 2.新增chomd權限設置功能 * 3.新增rename重命名功能 * 4.新增新建文件和目錄功能 * 5.類SuFileEditor重構為SuExplorer,類方法改為靜態方法 * 6.新增主配置文件功能 * 7.重構頁面邏輯,改為腳本混合代碼,便於閱讀 * 8.基於絕對路徑操作改為基於網站根目錄的相對路徑操作 * @since 3.1 <2016-9-13> SoChishun * 1. 新增文件上傳功能 * @since 3.2 <2017-8-23> SoChishun * 1. 修正無法查看腳本文件的問題 * 2. 對html輸出增加htmlspecialchars過濾功能 */ // 程序版本號 [2015-10-7] Added. $version = '3.2'; // session鍵名 [2015-10-7] Added. $sess_id = 'sess_suexplorer'; // 權限規則 [2015-10-7] Added. $prules = array('delfile', 'deldir', 'savefile', 'newfile', 'mkdir', 'renamefile', 'renamedir', 'chomdfile', 'chomddir', 'zip', 'unzip'); // 主配置 [2015-10-7] Added. $config = array( /* 用戶配置 */ 'users' => array( 'admin' => array('admin123', array('allow' => array(), 'forbit' => array())), 'test' => array('testpwd', array('allow' => array(), 'forbit' => array())), ), ); // 登錄信息 [2015-10-7] Added. $login_data = isset($_SESSION[$sess_id]) ? $_SESSION[$sess_id] : false; $action = I('action'); $view = I('view'); $path = I('path', '/'); // urldecode($_GET['path']) $_SERVER['DOCUMENT_ROOT'] $parent_path = path_getdir($path); switch ($action) { case 'login': // 用戶登錄 if (!SuExplorer::user_login($config, $sess_id, $msg)) { redirect('?r=fail', 1, $msg); } else { redirect('?r=ok'); } break; case 'logout': // 注銷登錄 SuExplorer::user_logout($sess_id); redirect('?r=ok'); break; case 'del': // 刪除路徑(文件或目錄) if (!SuExplorer::act_delete_path($path, $msg)) { redirect('?path=' . $path, 1, $msg); } else { redirect('?path=' . path_getdir($path), 1, '恭喜,操作成功!'); } break; case 'savefile': // 保存文件 case 'save_newfile': // 新建文件 if (!SuExplorer::act_save_file($msg)) { redirect('?path=' . $path, 1, $msg); } else { redirect('?path=' . $path, 1, '恭喜,操作成功!'); } break; case 'save_newdir': // 新建目錄 if (!SuExplorer::act_save_newdir($msg)) { redirect('?path=' . $path, 1, $msg); } else { redirect('?path=' . $path, 1, '恭喜,操作成功!'); } break; case 'upload_file': // 上傳文件 if (!SuExplorer::act_upload_file($msg)) { redirect('?path=' . $path, 1, $msg); } else { redirect('?path=' . $path, 1, '恭喜,文件上傳成功!'); } break; case 'rename_path': // 重命名路徑(文件或目錄) if (!SuExplorer::act_rename_path($msg)) { redirect('?path=' . $path, 1, $msg); } else { redirect('?path=' . pathinfo($path, PATHINFO_DIRNAME), 1, '恭喜,操作成功!'); } break; case 'chmod_path': // 修改權限(文件或目錄) if (!SuExplorer::act_chmod_path($msg)) { redirect('?path=' . $path, 1, $msg); } else { redirect('?path=' . $path, 1, '恭喜,操作成功!'); } break; case 'zip': // 壓縮 if (!SuExplorer::act_zip($msg)) { redirect('?path=' . $path, 1, $msg); } else { redirect('?path=' . $path, 1, '恭喜,操作成功!'); } break; case 'unzip': // 解壓縮 if (!SuExplorer::act_unzip($msg)) { redirect('?path=' . $path, 1, $msg); } else { redirect('?path=' . $path, 1, '恭喜,操作成功!'); } break; } ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>SuExplorer-<?php echo $version ?></title> <script src="//code.jquery.com/jquery-1.11.3.min.js"></script> <style type="text/css"> body {font-size:12px; color:#333;} a{text-decoration: none;} textarea{font-size:12px;line-height:18px; padding:5px;} th{font-weight: normal;} .userbar a:before{content: '['} .userbar a:after{content: ']'} .dir-contents{width:1050px; display:table;} .dir-contents a{ margin-right:20px;line-height:21px;text-decoration:none;float:left;} .blue{color:#0000DB} .lightblue{color:#1bd1a5} .purple{color:#9900ff} .green{color:#009900} .red{color:#F00} .grey {color:#999;} .nav { line-height: 18px;} .nav a { color:#333;} .nav a:before { content: ' » ' } .nav a:first-child:before {content: ''} .nav div { color:#CCC; border-bottom:solid 1px #CCC; margin-bottom:5px;} </style> </head> <body> <?php if ($login_data): ?> <!-- 用戶信息欄 --> <div class="userbar"> 歡迎您, <?php echo $login_data['user_name'] ?> <a href="?action=logout">注銷</a> <a href="?view=newfile&path=<?php echo $parent_path ?>">新建文件</a> <a href="?view=upload&path=<?php echo $parent_path ?>">上傳文件</a> <a href="?view=newdir&path=<?php echo $parent_path ?>">新建目錄</a> <a href="?view=zip&path=<?php echo $parent_path ?>">打包目錄</a> <a href="?view=unzip&path=<?php echo $parent_path ?>">解壓目錄</a> </div> <!-- /用戶信息欄 --> <!-- 路徑欄 --> <div> <form method="get" action="#" id="frm-path"> <input type="text" name="path" value="<?php echo $path ?>" style="width:50%;color:#333;padding:0px 2px;" required="required" /> <input type="hidden" id="action" name="action" value="" /> <input type="hidden" id="do" name="do" value="" /> <button type="submit">轉到</button> <button type="button" onclick="return del_cofirm('frm-path', '刪除');">刪除</button> <button type="button" data-path="<?php echo $path ?>" onclick="go_url(this, 'rename')">重命名</button> <button type="button" data-path="<?php echo $path ?>" onclick="go_url(this, 'chmod')">權限</button> </form> </div> <!-- /路徑欄 --> <div><?php SuExplorer::index($view, $path) ?></div> <!-- 腳本區 --> <script type="text/javascript"> /** * 刪除確認 * @param {type} form_id * @param {type} act_name * @returns {Boolean} * @since 1.0 <2015-10-7> SoChishun Added. */ function del_cofirm(form_id, act_name) { if (!confirm('您確定要' + act_name + '嗎?')) { return false; } var i = 0; function confirmx() { i++; return confirm(i + '.重要的操作要重復問三遍,您確定要' + act_name + '嗎?'); } while (i < 3) { if (!confirmx()) { return false; } } document.getElementById("action").value = "del"; document.getElementById("do").value = "yes"; document.getElementById(form_id).submit(); } /** * 跳轉到鏈接 * @param {HtmlButton} btn * @since 1.0 <2015-10-9> SoChishun Added. */ function go_url(btn, view) { location.href = '?path=' + $(btn).data('path') + '&view=' + view; } </script> <!-- /腳本區 --> <?php else: ?> <!-- 用戶登錄表單 --> <form method="post"> <table> <tr><th>用戶名:</th><td><input type="text" name="uname" placeholder="用戶名" required="required" /></td></tr> <tr><th>密 碼:</th><td><input type="password" name="upwd" placeholder="密碼" required="required" /></td></tr> </table> <input type="hidden" name="action" value="login" /> <button type="submit">登錄</button> <button type="reset">重置</button> </form> <!-- /用戶登錄表單 --> <?php endif; ?> </body> </html> <?php /* * **************************************************************************************************** 函數 :) * **************************************************************************************************** */ /** * 獲取瀏覽器參數 * @param string $name * @param mixed $defv * @return mixed * @since 1.0 <2015-8-13> SoChishun Added. */ function I($name, $defv = '') { if (isset($_GET[$name])) { return $_GET[$name]; } return isset($_POST[$name]) ? $_POST[$name] : $defv; } /** * URL重定向 * @param string $url 重定向的URL地址 * @param integer $time 重定向的等待時間(秒) * @param string $msg 重定向前的提示信息 * @return void * @since 1.0 <2015-10-7> from ThinkPHP */ function redirect($url, $time = 0, $msg = '') { //多行URL地址支持 $url = str_replace(array("\n", "\r"), '', $url); if (empty($msg)) $msg = "系統將在{$time}秒之后自動跳轉到{$url}!"; if (!headers_sent()) { // redirect if (0 === $time) { header('Location: ' . $url); } else { header("refresh:{$time};url={$url}"); echo($msg); } exit(); } else { $str = "<meta http-equiv='Refresh' content='{$time};URL={$url}'>"; if ($time != 0) $str .= $msg; exit($str); } } /** * 獲取文件擴展名類型 * @param string $exten 擴展名(不帶.) * @return string * @since 1.0 <2015-10-9> SoChishun Added. */ function get_exten_catetory($exten) { if ($exten) { $filetypes = array('zip' => array('zip', 'rar', '7-zip', 'tar', 'gz', 'gzip'), 'doc' => array('txt', 'rtf', 'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'wps', 'et'), 'script' => array('php', 'js', 'css', 'c'), 'image' => array('jpg', 'jpeg', 'png', 'gif', 'tiff', 'psd', 'bmp', 'ico')); foreach ($filetypes as $catetory => $extens) { if (in_array($exten, $extens)) { return $catetory; } } } return ''; } /** * 絕對路徑轉相對路徑 * @param string $path * @return string * @since 1.0 <2015-10-9> SoChishun Added. */ function path_ator($path) { $root = $_SERVER['DOCUMENT_ROOT']; $path = substr($path, strlen($root)); if ('/' != DIRECTORY_SEPARATOR) { $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); } return $path; } /** * 相對路徑轉絕對路徑 * @param string $path * @return string * @since 1.0 <2015-10-9> SoChishun Added. */ function path_rtoa($path) { $root = $_SERVER['DOCUMENT_ROOT']; if ('/' != DIRECTORY_SEPARATOR) { $path = str_replace('/', DIRECTORY_SEPARATOR, $path); } return $root . $path; } /** * 獲取文件的目錄地址 * @param string $path * @param boolean $is_r 是否相對路徑 * @return string * @since 1.0 <2015-10-9> SoChishun Added. */ function path_getdir($path, $is_r = true) { if (!$path || is_dir($is_r ? path_rtoa($path) : $path)) { return $path; } return pathinfo($path, PATHINFO_DIRNAME); } /** * 頁面主類 * @since 1.0 <2015-5-11> SoChishun <14507247@qq.com> Added. * @since 3.0 <2015-10-7> SoChishun 重構. */ class SuExplorer { /** * 版本號 * @var string * @since 1.0 <2015-10-7> SoChishun Added. */ CONST VERSION = '3.0.0'; /** * 顯示網站目錄的項目內容 * @since 1.0 <2015-5-11> SoChishun Added. */ static function index($view, $path) { // 面包屑導航 self::location_to_breadcrumb($path); // 視圖顯示 switch ($view) { case 'newfile': self::view_create_file($path); break; case 'newdir': self::view_create_dir($path); break; case 'upload': self::view_upload_file($path); break; case 'rename': self::view_rename_path($path); break; case 'chmod': self::view_chmod_path($path); break; case 'zip': self::view_zip(); break; case 'unzip': self::view_unzip(); break; default: // 列出文件 $sapath = path_rtoa($path); if (is_dir($sapath)) { self::view_content_list($path); } else if (is_file($sapath)) { self::view_edit_file($path); } else { echo '<strong class="red">文件或目錄不存在或已刪除!</strong>'; } break; } } /** * 用戶登錄操作 * @param array $config * @param string $sess_id * @param string $msg 錯誤消息 * @return boolean * @since 1.0 <2015-10-9> SoChishun Added. */ static function user_login($config, $sess_id, &$msg = '') { if (!$_POST || !isset($_POST['uname'])) { $msg = '表單數據無效!'; return false; } $uname = $_POST['uname']; if (!array_key_exists($uname, $config['users'])) { $msg = '用戶不存在'; return false; } $login_data = $config['users'][$uname]; if ($login_data[0] != $_POST['upwd']) { $msg = '密碼錯誤!'; return false; } $_SESSION[$sess_id] = array('user_name' => $uname, 'rules' => isset($login_data[1]) ? $login_data[1] : false); return true; } /** * 用戶登出操作 * @param string $sess_id * @return boolean * @since 1.0 <2015-10-9> SoChishun Added. */ static function user_logout($sess_id) { if (isset($_SESSION[$sess_id])) { unset($_SESSION[$sess_id]); } return true; } /** * 刪除路徑(文件或目錄) * @param string $path 路徑 * @param string $msg 錯誤消息 * @return boolean|string * @since 1.0 <2015-10-7> SoChishun Added. * @since 2.0 <2015-10-8> SoChishun 將delete_file和delete_dir合並到delete_path */ static function act_delete_path($path, &$msg = '') { if ('yes' != I('do')) { // 為防止黑客破壞,刪除操作需要手動增加參數do=yes $msg = '非法操作!'; return false; } if ('/' == $path) { $msg = '根目錄無法刪除!'; return false; } $path = path_rtoa($path); if (is_file($path)) { if (!@unlink($path)) { $msg = '文件刪除失敗!'; return false; } return true; } if (is_dir($path)) { if (!@rmdir($path)) { $msg = '目錄刪除失敗!(非空目錄或權限不足)'; return false; } return true; } $msg = '不是有效文件或目錄!'; return false; } /** * 保存(新)文件 * @param type $msg * @return boolean * @since 1.0 <2015-10-7> SoChishun Added. */ static function act_save_file(&$msg = '') { $filename = I('filename'); if (!$filename || !strpos($filename, '.')) { $msg = '文件擴展名無效!'; return false; } $content = I('content'); $path = I('path'); $path = path_rtoa($path); if (is_file($path)) { $path = path_getdir($path, false); } $newpath = $path . DIRECTORY_SEPARATOR . $filename; try { file_put_contents($newpath, $content); return true; } catch (Exception $ex) { $msg = $ex->getMessage(); return false; } } /** * 保存新目錄 * @param string $msg 錯誤消息 * @return boolean * @since 1.0 <2015-10-8> SoChishun Added. */ static function act_save_newdir(&$msg = '') { $filename = I('filename'); if (!$filename) { $msg = '目錄名稱無效'; return false; } $path = path_rtoa(I('path')); $newpath = $path . DIRECTORY_SEPARATOR . $filename; try { mkdir($newpath, I('mode')); return true; } catch (Exception $ex) { $msg = $ex->getMessage(); return false; } } /** * 上傳文件 * @param type $msg * @return boolean * @since 1.0 <2016-9-13> SoChishun Added. */ static function act_upload_file(&$msg = '') { if ($_FILES["file"]["error"] > 0) { $msg = $_FILES["file"]["error"]; return false; } $path = I('path'); $path = path_rtoa($path); $filename = $_FILES["file"]["name"]; if (file_exists($path . $filename)) { $msg = $filename . " 文件已存在!"; return false; } move_uploaded_file($_FILES["file"]["tmp_name"], $path . $filename); return true; } /** * 重命名路徑操作 * @param string $msg 錯誤消息 * @return boolean * @since 1.0 <2015-10-9> SoChishun Added. */ static function act_rename_path(&$msg = '') { $filename2 = I('filename2'); if (!$filename2) { $msg = '新名稱未填寫!'; return false; } $path = path_rtoa(I('path')); if (is_file($path) && !strpos($filename2, '.')) { $msg = '文件擴展名無效!'; return false; } try { $newname = pathinfo($path, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR . $filename2; @rename($path, $newname); return true; } catch (Exception $ex) { $msg = $ex->getMessage(); return false; } } /** * 編輯權限操作 * @param string $msg 錯誤消息 * @return boolean * @since 1.0 <2015-10-9> SoChishun Added. */ static function act_chmod_path(&$msg = '') { $mode = I('mode'); if (!$mode) { $msg = '權限模式無效!'; return false; } $path = path_rtoa(I('path')); try { chmod($path, $mode); return true; } catch (Exception $ex) { $msg = $ex->getMessage(); return false; } } /** * 壓縮操作 * @param string $msg * @return boolean * @since 1.0 <2015-10-9> SoChishun Added. */ static function act_zip(&$msg = '') { $filename = I('filename'); $content = I('content'); if (!$filename || !strpos($filename, '.')) { $msg = '壓縮文件名無效!'; return false; } if (!$content) { $msg = '壓縮內容無效!'; return false; } $include = array(); $exclude = array(); $paths = explode(PHP_EOL, $content); foreach ($paths as $path) { if (0 === strpos($path, 'exclude ')) { $exclude[] = trim(substr($path, 8)); } else { $include[] = $path; } } if (!$include) { $msg = '壓縮內容無效!'; return false; } $zip = new ZipHelper(); return $zip->zip($filename, $msg, $include, $exclude, I('rootpath')); } /** * 解壓縮文件 * @param type $msg * @return type */ static function act_unzip(&$msg = '') { $root = I('root'); $filename = I('filename'); if (!$filename) { $msg = '壓縮文件路徑無效!'; return false; } if (!$root) { $msg = '解壓縮路徑無效!'; return false; } $zip = new ZipHelper(); return $zip->unzip($filename, $root, $msg); } /** * 目錄內容視圖 * @param type $path * @since 1.0 <2015-5-11> SoChishun Added. */ static function view_content_list($path) { $files = self::get_dir_contents($path, array('name' => true, 'path' => false, 'real_path' => false, 'relative_path' => true, 'exten' => false, 'ctime' => false, 'mtime' => false, 'size' => false, 'is_dir' => true, 'is_file' => false, 'is_link' => true, 'is_executable' => true, 'is_readable' => false, 'is_writable' => false, 'filetype' => true)); echo '<div class="dir-contents" title="藍色表示目錄,綠色表示可執行文件,淺藍色表示鏈接文件,紅色表示壓縮文件,紫色表示圖形文件,灰色表示其他文件">'; foreach ($files as $file) { if ($file['is_dir']) { echo '<a href="?path=' . $file['relative_path'] . '" class="blue"><strong>' . $file['name'] . '</strong></a>'; } else { $class = ''; if ($file['is_link']) { $class = 'lightblue'; } else if ($file['is_executable']) { $class = 'green'; } else { switch ($file['filetype']) { case 'zip': $class = 'red'; break; case 'image': $class = 'purple'; break; default: $class = 'grey'; break; } } echo '<a href="?path=' . $file['relative_path'] . '" class="' . $class . '">' . $file['name'] . '</a>'; } } echo '<div style="clear:both"></div></div>'; } /** * 文件內容編輯視圖 * @param type $path * @since 1.0 <2015-5-11> SoChishun Added. */ static function view_edit_file($path) { $sapath = path_rtoa($path); if (!is_file($sapath)) { return; } $category = get_exten_catetory(pathinfo($path, PATHINFO_EXTENSION)); switch ($category) { case 'doc': case 'script': $btns = '<button type="submit">保存</button><button type="reset">重置</button>'; if (!is_writable($sapath)) { echo '<div style="color:#F00">文件不可寫</div>'; $btns = ''; } echo '<div> <form method="post"> ', $btns, '<div><textarea name="content" cols="60" rows="36" style="width:90%">' . htmlspecialchars(file_get_contents($sapath)) . '</textarea></div>', $btns, ' <input type="hidden" name="action" value="savefile" /> <input type="hidden" name="filename" value="' . basename($path) . '" /> <input type="hidden" name="path" value="' . $path . '" /> </form> </div>'; break; case 'image': echo '<img src="', $path, '" alt="" style="max-width:800px;max-height:640px;" /><br />'; echo basename($path); echo ' <a href="', $path, '" target="_blank">[原圖]</a>'; break; default: echo basename($path); echo ' <a href="', $path, '" target="_blank">[下載]</a>'; break; } } /** * 新增文件視圖 * @param string $path 路徑 * @since 1.0 <2015-10-8> SoChishun Added. */ static function view_create_file($path) { echo '<div> <form method="post"> <table> <tr><th>文件名:</th><td><input type="text" name="filename" required="required" placeholder="如:newfile.txt" /></td></tr> <tr><th valign="top">內容:</th><td><textarea name="content" cols="90" rows="12"></textarea></td></tr> <tr><td> </td><td><button type="submit">創建文件</button><button type="reset">重置</button></td></tr> </table> <input type="hidden" name="action" value="save_newfile" /> <input type="hidden" name="path" value="' . $path . '" /> </form> </div>'; } /** * 新增目錄視圖 * @param string $path 路徑 * @since 1.0 <2015-10-8> SoChishun Added. */ static function view_create_dir($path) { echo '<div> <form method="post"> 目錄名:<input type="text" name="filename" required="required" /><br /> 權限模式:<input type="text" name="mode" required="required" value="0777" /><br /> <button type="submit">創建目錄</button> <button type="reset">重置</button> <input type="hidden" name="action" value="save_newdir" /> <input type="hidden" name="path" value="' . $path . '" /> </form> </div>'; } static function view_upload_file($path) { echo '<div> <form method="post" enctype="multipart/form-data"> <table> <tr><th>選擇文件:</th><td><input type="file" name="file" required="required" /></td></tr> <tr><td> </td><td><button type="submit">立即上傳</button> <button type="reset">重置</button></td></tr> </table> <input type="hidden" name="action" value="upload_file" /> <input type="hidden" name="path" value="' . $path . '" /> </form> </div>'; } /** * 重命名文件視圖 * @param string $path 路徑 * @since 1.0 <2015-10-8> SoChishun Added. */ static function view_rename_path($path) { echo '<div> <form method="post"> 原名稱:<input type="hidden" name="filename" value="' . basename($path) . '" />' . basename($path) . '<br /> 新名稱:<input type="text" name="filename2" required="required" /><br /> <button type="submit">重命名</button> <button type="reset">重置</button> <input type="hidden" name="action" value="rename_path" /> <input type="hidden" name="path" value="' . $path . '" /> </form> </div>'; } /** * 編輯權限視圖 * @param string $path 路徑 * @since 1.0 <2015-10-9> SoChishun Added. */ static function view_chmod_path($path) { echo '<div> <form method="post"> 名稱:' . basename($path) . '<br /> 權限模式:<input type="text" name="mode" required="required" value="0777" /><br /> <button type="submit">設置</button> <button type="reset">重置</button> <input type="hidden" name="action" value="chmod_path" /> <input type="hidden" name="path" value="' . $path . '" /> </form> </div>'; } /** * 壓縮文件視圖 * @since 1.0 <2015-10-9> SoChishun Added. */ static function view_zip() { echo '<div> <form method="post"> <table> <tr><th>壓縮文件名:</th><td><input type="text" name="filename" required="required" size="89" placeholder="絕對路徑,如:C:\public\www\website1\newfile.zip" /></td></tr> <tr><th valign="top">壓縮內容:</th><td><textarea name="content" cols="90" rows="12" placeholder="每個路徑一行,必需是絕對路徑"></textarea></td></tr> <tr><th>去除根路徑:</th><td><input type="text" name="rootpath" size="89" placeholder="絕對路徑,如:C:\public\www\website1" /></td></tr> <tr><td> </td><td class="red"> 注意,所有路徑都必需是絕對路徑!<br /> 包含路徑示例:C:\public\www\website1\app<br /> 排除路徑示例: exclude C:\public\www\website1\app\runtime<br /> 如果填寫跟路徑地址,則壓縮內容會自動去除跟路徑信息(解壓縮的時候,可以解壓縮到任意目錄下),如果根路徑為空則保留根路徑信息(解壓縮的時候,無法解壓縮到任意目錄下,系統會自動創建和壓縮前路徑一樣的目錄) </td></tr> <tr><td> </td><td><button type="submit">創建壓縮文件</button><button type="reset">重置</button></td></tr> </table> <input type="hidden" name="action" value="zip" /> </form> </div>'; } /** * 解壓縮文件視圖 * @since 1.0 <2015-10-9> SoChishun Added. */ static function view_unzip() { echo '<div> <form method="post"> <table> <tr><th>壓縮文件名:</th><td><input type="text" name="filename" required="required" size="89" placeholder="絕對路徑,如:C:\public\www\website1\newfile.zip" /></td></tr> <tr><th>解壓縮路徑:</th><td><input type="text" name="root" required="required" size="89" placeholder="絕對路徑,如:C:\public\www\website1" /></td></tr> <tr><td> </td><td><button type="submit">解壓縮文件</button><button type="reset">重置</button></td></tr> </table> <input type="hidden" name="action" value="unzip" /> </form> </div>'; } /** * 返回指定路徑下的內容 * @param string $directory 路徑 * @param array $config 選項 * @return array * @throws Exception * @since 1.0 <2015-5-11> SoChishun Added. * @since 1.1 <2015-10-8> SoChishun 新增filetype文件類別屬性 */ static function get_dir_contents($directory, $options = array()) { $config = array('name' => true, 'path' => true, 'real_path' => true, 'relative_path' => false, 'exten' => false, 'ctime' => false, 'mtime' => false, 'size' => false, 'is_dir' => true, 'is_file' => false, 'is_link' => false, 'is_executable' => false, 'is_readable' => false, 'is_writable' => false, 'filetype' => false); if ($options) { $config = array_merge($config, $options); } try { $dir = new DirectoryIterator(path_rtoa($directory)); } catch (Exception $e) { throw new Exception($directory . ' is not readable'); } $files = array(); foreach ($dir as $file) { if ($file->isDot()) { continue; } if ($config['name']) { $item['name'] = $file->getFileName(); } if ($config['path']) { $item['path'] = $file->getPath(); } if ($config['real_path']) { $item['real_path'] = $file->getRealPath(); } if ($config['relative_path']) { $item['relative_path'] = path_ator($file->getRealPath()); } $exten = $file->getExtension(); if ($config['exten']) { $item['exten'] = $exten; } if ($config['filetype']) { $item['filetype'] = get_exten_catetory($exten); } if ($config['mtime']) { $item['mtime'] = $file->getMTime(); } if ($config['ctime']) { $item['ctime'] = $file->getCTime(); } if ($config['size']) { $item['size'] = $file->getSize(); } if ($config['is_dir']) { $item['is_dir'] = $file->isDir(); } if ($config['is_file']) { $item['is_file'] = $file->isFile(); } if ($config['is_link']) { $item['is_link'] = $file->isLink(); } if ($config['is_executable']) { $item['is_executable'] = $file->isExecutable(); } if ($config['is_readable']) { $item['is_readable'] = $file->isReadable(); } if ($config['is_writable']) { $item['is_writable'] = $file->isWritable(); } $files[] = $item; } return $files; } /** * 路徑轉為導航 * @param string $path * @since 1.0 <2015-5-11> SoChishun Added. */ static function location_to_breadcrumb($path) { echo '<div class="nav"><a href="?path=/">/</a>'; if ('/' != $path) { $asubpath = explode('/', substr($path, 1)); if ($asubpath) { $str = ''; foreach ($asubpath as $sub) { $str .= '/' . $sub; echo '<a href="?path=', $str, '">', $sub, '</a>'; } } } echo '<div>', path_rtoa($path), '</div>'; echo '</div>'; } } /** * 壓縮類 * @since 1.0 <2015-10-9> SoChishun Added. */ class ZipHelper { /** * 解壓縮之 * @param type $filename * @param type $root * @param type $msg * @return boolean * @since 1.0 <2015-10-9> SoChishun Added. */ function unzip($filename, $root, &$msg = '') { if (!$filename) { $msg = '壓縮文件名無效!'; return false; } $zip = new ZipArchive(); $msg = $zip->open($filename); if (true !== $msg) { $msg = var_export($msg, true); return false; } $zip->extractTo($root); $zip->close(); return true; } /** * 壓縮之 * @param type $filename * @param type $msg * @param type $include * @param type $exclude * @param string $trimpath * @param string $comment * @return boolean * @since 1.0 <2015-10-9> SoChishun Added. */ function zip($filename, &$msg = '', $include = array(), $exclude = array(), $trimpath = '', $comment = 'default') { if (!$filename) { $msg = '壓縮文件名無效!'; return false; } if (!$include) { $msg = '壓縮內容無效!'; return false; } if ('default' == $comment) { $comment = basename($filename) . PHP_EOL . 'Generate at ' . date('Y-m-d H:i:s') . PHP_EOL . 'Powerd by SuExplorer.'; // 注釋內容 } try { $zip = new ZipArchive(); $msg = $zip->open($filename, ZIPARCHIVE::OVERWRITE); if (true !== $msg) { $msg = var_export($msg, true); return false; } if ($comment) { $zip->setArchiveComment($comment); } if ($trimpath) { $trimpath = rtrim($trimpath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; } $substart = strlen($trimpath); foreach ($include as $source) { $this->zip_dir($zip, $source, $exclude, $substart); } $zip->close(); return true; } catch (Exception $ex) { $msg = $ex->getMessage(); return false; } } /** * 遞歸壓縮整個目錄 * @param ZipArchive $zip * @param string $source 包含的路徑 * @param array $exclude 排除的路徑 * @param int $substart 開始截取的路徑字符串(用於去除路徑中的根目錄路徑) * @since 1.0 <2015-8-28> SoChishun Added. */ function zip_dir(&$zip, $source, $exclude, $substart = 0) { if (is_dir($source)) { $source = rtrim($source, DIRECTORY_SEPARATOR); if ($handle = opendir($source)) { while (false !== ( $f = readdir($handle) )) { if ('.' == $f || '..' == $f) { continue; } $filename = $source . DIRECTORY_SEPARATOR . $f; if (is_dir($filename)) { if ($exclude && in_array($filename, $exclude)) { continue; } $this->zip_dir($zip, $filename, $exclude, $substart); } else { if ($exclude && in_array($filename, $exclude)) { continue; } $zip->addFile($filename, substr($filename, $substart)); } } closedir($handle); } } else { if ($exclude && in_array($source, $exclude)) { return; } $zip->addFile($source); } } }