基于PHP的定时交作业系统
前言
????最近有個需求,就是宿舍的學委要去飛去銀川參加程序設計國際區域賽了。由于比賽期間不能帶電腦,身為宿友的我看他因收作業沒時間收而感到有一點點同情,肯定不是因為他要給我帶特產我才寫的!于是在兩天的有空的時間余下給他寫了個交作業系統。PHP實現在指定時間打包文件夾以及將其作為附件發送到指定郵箱,此項目技術棧沒有用任何架構。純屬基礎。
文章目錄
- 前言
- 實現的功能
- 重要功能的實現方法
- 發送郵件
- 時間精確判斷
- 壓縮文件
- 任務執行文件
- 文件夾操作
- 實現原理
- 準備工作
- 步驟
- 實戰: 效果截圖
- 演示視頻:
- 總結
- 偶爾遇到的坑
- 感慨
實現的功能
????同學可以上傳作業文件,后臺接收發起者指定類型和大小范圍內的文件并將其放在生成的作業鏈接【這里采用md5校驗】文件夾下,發起者可以設置交作業的開始時間和結束時間,作業標題和格式,各種消息通知,設置是否時間結束自動發送還是認為發送,下載打包文件,可以自由添加學生名單,時間一結束將系統自動打包作業文件夾并命名好指定名字將其發送到指定目標郵件。
重要功能的實現方法
- 發送郵件
- 時間精確判斷
- 壓縮文件
- 執行任務文件
- 文件以及文件夾操作
- 公眾號登入,提交多次
發送郵件
1.打開qq郵箱。點擊設置【這里我使用的是qq郵箱,你也可以使用163】
2.點擊賬戶
3.點擊開啟smtp服務
4.獲取授權碼、【沒有這個系統沒有權限使用你的郵箱發送郵件】
5.重點
你需要了解到 php最多人用的發送email的sdk是什么。并不是自帶的核心email函數。而是PHPMailer這個神奇的功能api包。點擊到Github下載
使用方法:
將 PHPMailer-master項目文件夾放至指定位置,然后通過引用的方式進行調用
這里我放在了項目根目錄下。
代碼:
時間精確判斷
????很簡單的算法,對于執行時間判斷條件,需要用當前時間的毫秒數,從格林威治時間到現在的毫秒數。去比較交作業開始時間和交作業結束時間,去減,如果當前時間減去開始時間大于0,那么已經開始,計算當前時間減去結束時間,如果大于0,那么已結束,否則取差的絕對值,然后將毫秒轉換成普通用戶看的標準的日期時間格式,距離結束還有XX。如果當前時間減去開始時間小于0,那么沒有開始,取差的絕對值,后將毫秒轉換成普通用戶看的標準的日期時間格式,距離開始還有XX。
核心計算函數:strtotime()//轉化為格林威治毫秒代碼
$statue = 0;//$data[6]就是 開始時間或者結束時間.可以換$T = strtotime($data[6]);$all = floor((time()-$T));if($all>0){$statue = 0;echo('已結束!');}else{$T = strtotime($data[5]);$all = floor((time()-$T));if($all>0){echo('已經開始!剩余時間:');$statue = 1;$T = strtotime($data[6]);$all = floor(($T-time())); }else{$statue = 0;echo "未開始:倒計時";}$all = abs($all);// $dS = $all;// $dY = floor($all);// $dM = 0;$dD = floor($all/(3600*24));$all = $all-floor($all/60/60/24);$dH = floor($all/3600);$all = $all-floor($all/60/24);$dM = floor($all/60);$all = $all-floor($all/60);$dS = $all;//年月日時分秒////$all 得到的是多少分鐘以前 if ($dD>0){$finally_time = ($dD).'天';}else if($dH>0){$finally_time = $dH.'小時';}else if($dM>0){$finally_time = $dM.'分鐘';}else{$finally_time = $dS.'秒';}echo $finally_time;}任務執行判斷也是同理,這里不做敘述。
壓縮文件
壓縮文件夾,打包成zip的方式,如果下面的步驟你做完了,但是還是不成功,你可以去找到php.ini文件,開啟支持擴展方式,即可以在文尾加上一句話。
extension=php_zip.dll核心代碼:
error_reporting(0);ob_start();if(!$_GET['md5']){echo "沒有定義目錄";return ;}echo "打包中...<br>";$dataPath="receiveHomework/homeworks/".$_GET['md5']."/";//BUG$fileName = "17創新實驗班實驗1.zip";// 自定義打包 文件名命名 可以從數據庫讀取$fileName = iconv('utf-8','gb2312',$fileName);$fileName = $dataPath.$fileName;if(!file_exists($fileName)){//重新生成文件$zip = new ZipArchive();//php內置打包類if ($zip->open($fileName, ZIPARCHIVE::CREATE)!==TRUE) {exit('無法打開文件,或者文件創建失敗');}$datalist=list_dir($tmpPath);foreach($datalist as $val){if(file_exists($val)){$zip->addFile($val, str_replace($tmpPath, '', $val));}}$zip->close();}echo "<br>";//獲取上傳學生作業的文件列表$count = 0;function list_dir($dir){$result = array();if (is_dir($dir)){$file_dir = scandir($dir);foreach($file_dir as $file){if ($file == '.' || $file == '..'){continue;}elseif (is_dir($dir.$file)){$result = array_merge($result, list_dir($dir.$file.'/'));}else{array_push($result, $dir.$file);$count++;echo "正在打包第".$count." 份作業....<br>"; //這里,可能有多個作業,需要展示給前端頁面看具體打包過程。}}}return $result;}echo $_GET['md5']."<br>打包成功!";sleep(1);//打包后,發送郵件,匯報情況if($_GET['send']){header("location:send-time-Mail.php?x=".$_GET['x']);return ;}header("location:downloadFiles.php?md5=".$_GET['md5']."&filename=".$urlpara);任務執行文件
這里用啥方法都行,本人在這里定義用了XMLHttpRequest對象,方便使用FormData。
$(document).ready(function(){});function judge(){if(window.XMLHttpRequest){var request = new XMLHttpRequest();request.onreadystatechange=function(){if(request.readyState==4&&request.status==200){$('#div').prop('scrollTop',document.getElementById("div").scrollHeight);document.write(request.responseText);document.clear;if(request.responseText.indexOf("成功")!=-1){//notices sender sned ok//pirnt all each type data}}};request.open("GET",'handle_system_auto.php',true);request.send();}}window.setInterval(function (){judge();},8000);judge();文件夾操作
1.php移動指定文件夾下的tmp臨時文件
$success = move_uploaded_file($file_tmp,$path.$name);2.刪除指定目錄下的文件
unlink("./".$path.$name_edata);3.生成空文件夾
$dir = iconv("UTF-8", "GBK", $path2); if (!file_exists($dir)){mkdir ($dir,0777,true);//個人感覺挺多函數都跟系統命令差不多語法。echo "新建文件夾成功!";}4.獲取前端js FormData的post過來的file
$file = $_FILES['file'];$fileName = $_FILES['file']['name'];$file_tmp = $_FILES['file']['tmp_name'];實現原理
準備工作
注:服務器和云主機方面,如果想了解如何快速獲得一臺免費云主機免費服務器教程,1小時內即可讓別人訪問你的網站。可以留個言,本人會另外寫一篇關于1小時即可擁有自己的網站博客文章,免備案系列。
步驟
1.根據需求,設計作業的表。
作業表 對應的SQL語句如下
對于交了作業的同學,還需要記錄到另外一個表里。
CREATE TABLE `receiveStudentFile` ( `x` int(11) NOT NULL AUTO_INCREMENT , `md5FileName` char(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , `studentName` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL , `filename` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL , `uploadcount` int(11) NULL DEFAULT NULL , `uploadtime` char(25) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , `statue` int(11) NULL DEFAULT NULL , PRIMARY KEY (`x`) ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci AUTO_INCREMENT=64 ROW_FORMAT=DYNAMIC ;2.設計前端頁面
? ? ? ? 發起者的 設計新建作業、查看我的收作業、作業管理、交作業頁面。這里比較簡單,但比較花費時間,不做敘述。
3.功能編寫
? ? ? ?對于交作業的homework頁面,需要加載作業詳情。同時還應前后端判斷作業在改時間是否可上傳。 注:[考慮到開發只有2天以及使用用戶基數,所以沒采用前后端分離,采用前后端內嵌式]。
交作業homework頁面的代碼如下:
新建作業文件的代碼:
<?phperror_reporting(0);require_once('connect.php');if($_POST['title']&&$_COOKIE['userid']){$size = rand(1000,2000);$size = md5($size);$query = "insert into homework(`userid`, `path`, `title`, `format_`, `starttime`, `endtime`, `auto_sendemail`, `email`, `use_you_email`, `youemail`, `studentnum`, `noticesyou`, `student`, `buildtime`, `statue`) values(".$_COOKIE['userid'].",'".$size."','".$_POST['title']."','".$_POST['format']."','".$_POST['starttime']."','".$_POST['endtime']."','".$_POST['auto_send']."','".$_POST['auto_send_email']."','".$_POST['use_my']."','".$_POST['use_my_1']."',".$_POST['num'].",'".$_POST['notices']."','".$_POST['content']."','".date("Y-m-d H:i:s",time())."',0)";$result = mysqli_query($connect_to_database,$query);if($result){echo('新建成功!您這次交作業的鏈接,請保管好!| http://www.erremall.top/neusoftforum/php/homework.php?md5code='.$size);//需要建立文件夾$dir = iconv("UTF-8", "GBK", "receiveHomework/homeworks/".$size);if (!file_exists($dir)){mkdir ($dir,0777,true);}else{echo("建立失敗,已存在相同類型MD5,請重新提交");}}else{echo('服務器繁忙!');}} ?>后臺處理文件acceptHomework.php的代碼如下:
<?phperror_reporting(0);require_once('connect.php');header("Content-Type: text/html;charset=utf-8");if(!$_POST['md5']){echo "文件太大!文件最多不能超過200M";return ;}$md5 = $_POST['md5'];$_COOKIE['counts']++;$query_is_exist = "select * from homework where path='".$md5."'";$result = mysqli_query($connect_to_database,$query_is_exist);$this_result = mysqli_fetch_array($result);$T = strtotime($this_result[6]);$all = floor((time()-$T));if($all>0){echo "已結束";return ;}else{$T = strtotime($this_result[5]);$all = floor((time()-$T));if($all<0){echo "未開始";return ;}}$file = $_FILES['file'];$fileName = $_FILES['file']['name'];$file_tmp = $_FILES['file']['tmp_name'];$path = "receiveHomework/homeworks/".$md5."/";$path2 = "receiveHomework/homeworks/".$md5;$dir = iconv("UTF-8", "GBK", $path2);if (!file_exists($dir)){mkdir ($dir,0777,true);echo "新建文件夾成功!";}$path = "receiveHomework/homeworks/".$md5."/";$name = iconv('utf-8','gb2312',$fileName);//查找是否有這個同學,是否提交過,如果是,那么覆蓋$datanames = explode("\n",$this_result[13]);$name_ ="";$has_recode = false;$repeat = 0;for($i = 0;$i<count($datanames);$i++){if(strstr(trim($fileName),trim($datanames[$i]))===false){} else{$has_recode = true;$repeat = 1;$name_ = $datanames[$i];break;} // echo $datanames;}//repeat if($repeat==1){$query = "select x from userreceive where studentName='".$name_."' and md5='".$md5."'";$query = mysqli_query($connect_to_database,$query);$query = mysqli_fetch_array($query);if($query[0]!=""){echo "為防止其他同學惡意篡改,只有一次提交機會!";return ;}}if(strlen($this_result[13])>2){$query_has_sub ="select studentName,filename from userreceive where md5='".$md5."' and studentName='".$name_."'";$quee = mysqli_query($connect_to_database,$query_has_sub);$edata = mysqli_fetch_array($quee);if($edata[0]!=""){$repeat = 1;}else{$repeat = 0;}}else{$repeat = 0;}if($repeat==1){$name_edata = iconv('utf-8','gb2312',$edata[1]);unlink("./".$path.$name_edata);echo "更新文件成功!";}//查找 文件名有沒有出現在數據庫里,有,則覆蓋$sele_repeat_file = "select filename,x from userreceive where filename='".$fileName."'";$Q = mysqli_query($connect_to_database,$sele_repeat_file);$repeat_same_file = 0;$eeeeee = mysqli_fetch_array($Q);$repeat_file_id = $eeeeee[1];$eeeeee = $eeeeee[0];if($eeeeee[0]!=""){echo "已覆蓋文件";$name_edata = iconv('utf-8','gb2312',$fileName);unlink("./".$path.$name_edata);$repeat_same_file = 1;}//$success = move_uploaded_file($file_tmp,$path.$name);if($success){//新增 用戶信息//先搜索學生名字$names = "-";if(strlen($this_result[13])<2){echo "該作業沒有定義名單";}else{//有$dataname = explode("\n",$this_result[13]);$is_has = false;$names = "";for($i = 0;$i<count($dataname);$i++){if(strstr(trim($fileName),trim($dataname[$i]))===false){} else{$is_has = true;$names = $dataname[$i];break;}}if($is_has){if($repeat!=1)echo $names." 同學,提交成功啦!";}else{echo "該同學沒有找到,請注意格式或者聯系發起者更換名單!上傳的文件已刪除";unlink("./".$path.$name);return ;}}$timesq = $_COOKIE['counts'];if($timesq==0){$timesq = 1;}if($timesq==1){$has_fix = 0;}else{$has_fix = 1;}if($repeat==1||$repeat_same_file==1){if($repeat_same_file==1){$insert_data = "update userreceive set filename='".$fileName."',uploadtime='".Date("Y-m-d H:i:s",time())."',statue=1,uploadcount=".$timesq." where md5='".$md5."' and x=".$repeat_file_id; }else{$insert_data = "update userreceive set filename='".$fileName."',uploadtime='".Date("Y-m-d H:i:s",time())."',statue=1,uploadcount=".$timesq." where md5='".$md5."' and studentName='".$names."'"; }}else{$insert_data = "insert into userreceive( `md5`, `studentName`, `filename`, `uploadcount`, `uploadtime`, `statue`) values('".$md5."','".$names."','".$fileName."',".$timesq.",'".Date("Y-m-d H:i:s",time())."',".$has_fix.")"; }$result = mysqli_query($connect_to_database,$insert_data);if($result){if($repeat!=1){echo('上傳成功!'); }else{echo('更新成功!'); }}else{echo ("上傳失敗");}}else{echo '上傳失敗!請重試,可能是網絡的原因.';} ?>定時執行任務html文件:
<!doctype html> <html> <head> <meta charset="utf-8"> <script src="../js/jquery_need.js"></script> <title>自動發送系統</title> </head><body id="div"><div id="tip" style="width: 1000px;height: 500px;overflow-y: auto;margin: 0 auto;position: relative;top: 10vw;justify-content: center;display: flex;margin: 0 auto;word-break: break-all;word-wrap: break-word;">提示</div></body> </html> <script>$(document).ready(function(){});function judge(){if(window.XMLHttpRequest){var request = new XMLHttpRequest();request.onreadystatechange=function(){if(request.readyState==4&&request.status==200){ // $('#div').prop('scrollTop',document.getElementById("div").scrollHeight);document.write(request.responseText);document.clear;if(request.responseText.indexOf("success")!=-1){//notices sender sned ok// print relative data... For example, email send Result.}}};request.open("GET",'handle_system_auto.php',true);request.send();}}window.setInterval(function (){judge();},8000); //you can adjust exec time 。你可以改變執行時間judge(); </script>后臺定時處理php文件:
<?php//及時判斷。error_reporting(0);require_once('connect.php') ;//計算時間·段 $query_has_send = "select x,title,path,endtime from homework where statue=0";$query_is_exist = mysqli_query($connect_to_database,$query_has_send);while($every_homework = mysqli_fetch_array($query_is_exist)){$curr = strtotime($every_homework[3]);$rest = floor(time()-$curr);if($rest>=0){echo "編號:".$every_homework[0].",".$every_homework[1]." <a style='color:green;'>該作業可以打包發送了。</a><br>";//然后發送郵件給他 send mail for he//壓縮 run zip files.~header("location:zip_files.php?md5=".$every_homework[2]."&send=1&x=".$every_homework[0]);//發送郵件//郵件通知//更改結果//break;}else{echo $every_homework[1]." 時候未到,剩余:";$all = abs($rest);$dD = floor($all/(3600*24));$all = $all-floor($all/60/60/24);$dH = floor($all/3600);$all = $all-floor($all/60/24);$dM = floor($all/60);$all = $all-floor($all/60);$dS = $all;//年月日時分秒if ($dD>0){$finally_time = ($dD).'天';}else if($dH>0){$finally_time = $dH.'小時';}else if($dM>0){$finally_time = $dM.'分鐘';}else{$finally_time = $dS.'秒';}echo $finally_time."<br>";}} ?>后臺管理:
<?phperror_reporting(0); // class Handle{ // function Handle(){ // // // } // // }if(!$_GET['id']&&!$_GET['stopid']&&!$_GET['lateDate']&&!$_GET['sender']&&!$_GET['goaler']&&!$_GET['zip']){echo "抱歉,請求參數出現錯誤,請重新嘗試!";return ;}require_once('connect.php');if($_GET['id']){ //刪除 $id_md5_file = $_GET['id'];$name = "select filename,md5 from userreceive where x=".$id_md5_file;$name_query = mysqli_query($connect_to_database,$name);$name_set = mysqli_fetch_array($name_query);$name_set_data = $name_set[0];$md5data = $name_set[1];$query_update = "delete from userreceive where x = ".$id_md5_file;$end_result = mysqli_query($connect_to_database,$query_update);if($end_result){echo "刪除成功!";$path = "receiveHomework/homeworks/".$md5data."/";$name_edata = iconv('utf-8','gb2312',$name_set_data);unlink("./".$path.$name_edata);}else{echo "刪除失敗,請重新提交!";} }if($_GET['stopid']){//截止$Dtime = date("Y-m-d H:i:s",time());$name = "update homework set endtime='".$Dtime."' where x=".$_GET['stopid'];$name_query = mysqli_query($connect_to_database,$name);if($name_query){echo "截止成功!即將發送郵箱";}else{echo "截止失敗,服務器繁忙";}}if($_GET['lateDate']){//延期日期}if($_GET['sender']){//修改發送者的郵箱$name = "update homework set use_you_email='true',youemail='".$_GET['sender']."' where x=".$_GET['ttt'];$name_query = mysqli_query($connect_to_database,$name);if($name_query){echo "修改發送者郵箱成功!";}else{echo "修改失敗,服務器繁忙";}}if($_GET['goaler']){$name = "update homework set email='".$_GET['goaler']."' where x=".$_GET['ttt'];$name_query = mysqli_query($connect_to_database,$name);if($name_query){echo "修改接受者郵箱成功!";}else{echo "修改失敗,服務器繁忙";}//修改接受者的郵箱}if($_GET['zip']){$namewww = "17軟件工程創新實驗班實驗1.zip"; //可以修改命名格式$name = "select path from homework where x=".$_GET['x'];$name_query = mysqli_query($connect_to_database,$name);$name_set = mysqli_fetch_array($name_query); echo $name_set[0]."|".$namewww;} ?>實戰: 效果截圖
要實現這個功能,需要要一定的所有情況處理。需要以下全部文件:
1.新建作業:
新建成功
后臺管理:
交作業界面:
后臺接收的文件:
11點30分準時發送打包好的壓縮文件郵件,并且將沒有提交學生的名單羅列出來:
演示視頻:
上傳作業:
匹配同學(不在作業列表的同學無法交作業,這里發起者可后臺設定指定交作業同學)
判斷交作業是否含有指定同學名字
判斷格式;(格式不合格學委可能會聯系你,至于為什么不寫個自動生成作業格式算法?因為我不想讓同學變懶。。。)
交了之后可以下載(放心,絕對私密。后臺會生成臨時文件夾并在你下載之后秒刪除。服務器各級目錄權限也是配置好的。并且設置cookie和session雙重防護。不會讓你的文件泄露)和預覽
截止時間后,不能再提交。(后臺前端會雙重判斷驗證時間范圍有效性。所以卡頁面的時間卡法是沒用的,而且時間一到,系統會自動壓縮文件將它發送到指定老師的郵箱哦。你是沒機會交的。。只能補交了)
后臺查看交作業的同學,可以進行各種操作(作業叫錯了。只能叫學委在后臺刪除你的作業,重交。或者公眾號登入,綁定微信號后,可以提交多次呦)
公眾號登入!(中間時間是在找手機= =)
需要項目文件的感興趣的朋友,可以留言,會發過去。
項目部署步驟:
1.新建數據庫homeworkSet
2.注入項目中的sql文件
3.打開即可
總結
偶爾遇到的坑
1.使用語法對php進行文件刪除或者把tmp文件復制的過程中,需要將傳過來的文件名進行轉換,不然會亂碼。
方法:
感慨
總的來說,人是不斷進步的。多多運用所學知識去解決一些生活中的問題,才能將知識發揮用武之地。
總結
以上是生活随笔為你收集整理的基于PHP的定时交作业系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TypeScript等无法获取到歌曲播放
- 下一篇: C语言英尺和英寸换算米