实时同步脚本

来源:互联网 发布:疯狂java讲义下载 编辑:程序博客网 时间:2024/06/06 11:48

前一阵由于公司的项目需要,需要将一个服务网站上的文件库实时同步过来,包括其目录架构和内容,于是我写了一个脚本去在Linux上执行。
现在贴一下我写的脚本代码。

<?php // exit;set_time_limit(0);$conn=new PDO("mysql:host=xxx;dbname=xxx;","root","xxx");$conn->exec("SET NAMES 'utf8';");function writeLog($msg){//记录日志    if(!$msg) return false;    $dir = '/data/www/default/temp/';    $log = 'updatelog';    $filesize = filesize($dir.'/'.$log);    if($filesize>3145728){//设置log文件大小为3mb        rename($dir.'/'.$log,$dir.'/'.$log."".date('YmdH',time()));    }    $result = file_put_contents($dir.'/'.$log,(date('Y-m-d h:i:s',time())).'   '.$msg."\r\n",FILE_APPEND);    return $result;}function get_transid(){//取目录id关联表数据    global $conn;    $result = $conn->query("select * from transid");    $row = $result->fetchAll(PDO::FETCH_ASSOC);    $row_n = array();    foreach ($row as $key => $value) {        $row_n[$value['oldid']] = $value['id'];    }    $row_n[''] = 0;    return $row_n;}function addnavigation($pid,$arr){//更新category表中的navigation字段    global $conn;    if($pid!=0){        $result = $conn->query("select * from category where cid=".$pid);        $row = $result->fetch(PDO::FETCH_ASSOC);        $arr[] = array('cid'=>$row['cid'],'name'=>$row['name']);        $parentarr = addnavigation($row['pid'],$arr);        return $parentarr;    }else{        return $arr;    }}function writedata($dataArr,$flag=0,$table){//导入对比目录表    global $conn;    if(!in_array($table,array('tempdir2','file_compare'))){        return "tablename is wrong!";    }    if($flag==0){//先做清空        $res = $conn->exec("truncate table ".$table);        $arr = $conn->query("select count(1) as flag from ".$table);        $row = $arr->fetch(PDO::FETCH_ASSOC);        $flag = $row['flag']==0?1:0;        writedata($dataArr,$flag,$table);    }else{        //然后写入        if($table=='tempdir2'){            $stmt = $conn->prepare("insert into tempdir2 (id,catalogName,parentId,catalogRoutingNumber) values (:id,:name,:pid,:cnum)");            foreach ($dataArr as $key => $value) {                $arr = array(                    ':name' => $value['catalogName'],                    ':cnum' => $value['catalogRoutingNumber'],                    ':id' => $value['id'],                    ':pid' => $value['parentId']                );                $result = $stmt->execute($arr);            }        }elseif($table=='file_compare'){            $stmt = $conn->prepare("insert into file_compare (oldid,CatalogId,title,uploadUserName,uploadDate,newUptime,summary,isvisiableForuser,isdeleted,url) values (:oldid,:pid,:title,:uploadUserName,:uploadDate,:newUptime,:summary,:isvisiable,:isdeleted,:url)");            $id_arr = get_transid();//取目录id关联表            foreach ($dataArr as $key => $value) {                $time = strtotime(substr($value['uploadDate'],0,strlen($value['uploadDate'])-2));                $newUptime = strtotime(substr($value['newVersionUploaddate'],0,strlen($value['newVersionUploaddate'])-2));                if(in_array($value['knowledgeCatalogId'],array_keys($id_arr))){                    $pid = intval($id_arr[$value['knowledgeCatalogId']]);                }else{                    $pid = 0;                }                $arr = array(                    ':oldid' => $value['id'],                    ':pid' => $pid,                    ':title' => $value['title'],                    ':uploadUserName' => $value['uploadUserName'],                    ':uploadDate' => $time,                    ':newUptime' => $newUptime,                    ':summary' => $value['summary'],                    ':isvisiable' => intval($value['isvisiableForuser']),                    ':isdeleted' => intval($value['isdeleted']),                    ':yxturl' => $value['knowledgeUrl']                );                $result = $stmt->execute($arr);            }        }        return 1;    }}echo date("Y-m-d H:i:s")."运行开始 ———————————————— ";writeLog("【*****************检查更新开始********************】");//**********************************************************************************//获取接口数据//// CURLfunction curl_post($url,$arr){    $ch=curl_init();    curl_setopt($ch, CURLOPT_URL, $url);    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);    curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json; charset=utf-8"));//important    curl_setopt($ch, CURLOPT_POST, TRUE);    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($arr));    $data=curl_exec($ch);    curl_close($ch);    return json_decode($data,true);}function curl_post_del($url,$arr){    $ch=curl_init();    curl_setopt($ch, CURLOPT_URL, $url);    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);    curl_setopt($ch, CURLOPT_POST, TRUE);    curl_setopt($ch, CURLOPT_POSTFIELDS, $arr);    $data=curl_exec($ch);    curl_close($ch);    return json_decode($data,true);}function salt(){    $salt=rand(10000,99999);    return $salt;}$apikey="xxxxxxx";$secretkey="xxxxxxx";$salt1=salt();$salt2=salt();$signature1=hash('sha256',$secretkey.$salt1);$signature2=hash('sha256',$secretkey.$salt2);//获取文件数据$url1='http://url';$data1=array(    'apikey' => $apikey,    'salt' => $salt1,    'signature' => $signature1,    'kngCatalogId' => '',    'updateDate' => '',    'knowledgeTypes'=>'');$result1=curl_post($url1,$data1);$new_filedata=$result1['data'];// 获取目录数据$url2='http://url';$data2=array(    'apikey' => $apikey,    'salt' => $salt2,    'signature' => $signature2);$result2=curl_post($url2,$data2);$new_dirdata=$result2['data'];//**********************************************************************************//对比本地进行同步// 写入目录对比表writedata($new_dirdata,0,'tempdir2');//对比新旧目录$compare_sql = "SELECT t2.* from tempdir2 t2 LEFT JOIN tempdir t1 ON t1.id=t2.id && t1.catalogName=t2.catalogName && t1.parentId=t2.parentId && t1.catalogRoutingNumber=t2.catalogRoutingNumber WHERE t1.sid is null";$compareArr = $conn->query($compare_sql);$compareRow = $compareArr->fetchAll(PDO::FETCH_ASSOC);$category_add_arr = array();$category_update_arr = array();$navigation_row = array();if(count($compareRow)>0){    writeLog("【目录存在差异数据".count($compareRow)."条】");    //先对关联表进行全部更新    foreach ($compareRow as $key => $value) {        $id = $value['id'];        $catalogName = $value['catalogName'];        $parentId = $value['parentId'];        $catalogRoutingNumber = $value['catalogRoutingNumber'];        $result = $conn->query("select 1 from tempdir where id='".$id."'");        $row = $result->fetch(PDO::FETCH_ASSOC);         if(empty($row)){            $result_add = $conn->exec("insert into tempdir (id,catalogName,parentId,catalogRoutingNumber) values ('".$id."','".$catalogName."','".$parentId."','".$catalogRoutingNumber."')");//插入对比表            $result_add2 = $conn->exec("insert into transid (oldid) values ('".$id."')");//插入ID关联表  该表ID就是分类表cid            if($result_add>0 && $result_add2>0){                $value["newid"] = $conn->lastInsertId();                $category_add_arr[] = $value;            }else{                writeLog("【关联表或对比表插入失败】");            }        }else{            $result_update = $conn->exec("update tempdir set catalogName='".$catalogName."',parentId='".$parentId."',catalogRoutingNumber='".$catalogRoutingNumber."' where id='".$id."'");//修改对比表            if($result_update>0){                $category_update_arr[] = $value;            }else{                writeLog("【对比表更新失败】");            }        }    }    //取关联表数据    $dirid_arr = get_transid();    //再更新使用表    if(!empty($category_add_arr)){//插入目录树表        writeLog("【新条目".count($category_add_arr)."条】");        foreach ($category_add_arr as $key => $value) {            $pid = $dirid_arr[$value['parentId']];            $cid = $value['newid'];            $displayorder = $value['catalogRoutingNumber'];            $displayorder = substr($displayorder,strlen($displayorder)-3,strlen($displayorder));            $navigation_row[] = array('cid'=>$cid,'pid'=>$pid,'name'=>$catalogName,);            $result_add_c = $conn->exec("insert into category (cid,pid,name,displayorder,image,navigation,description) values ('".$cid."','".$pid."','".$catalogName."','".$displayorder."','','','')");            // echo "【插入结果:".$result_add_c."】\r\n";        }    }    if(!empty($category_update_arr)){//修改目录树表        writeLog("【变动条目".count($category_update_arr)."条】");        foreach ($category_update_arr as $key => $value) {            $pid = $dirid_arr[$value['parentId']];            $id = $dirid_arr[$value['id']];            $displayorder = $value['catalogRoutingNumber'];            $displayorder = substr($displayorder,strlen($displayorder)-3,strlen($displayorder));            $result_update_c = $conn->exec("update category set pid='".$pid."',name='".$value['catalogName']."',displayorder='".$displayorder."' where cid='".$id."'");            // echo "【修改结果:".$result_update_c."】\r\n";        }    }    foreach ($navigation_row as $key => $value) {//更改navigation字段        $arr = array();        if($value['pid']!=0){            $arr = addnavigation($value['cid'],$arr);        }else{            $arr[] = array('cid'=>$value['cid'],'name'=>$value['name']);        }        $navigation = addslashes(serialize($arr));        $conn->exec("update category set navigation='".$navigation."' WHERE cid=".$value['cid']);    }}else{    writeLog("【目录没有新变动】");}//**********************************************************************************//对比是否有删除//再次对比新旧目录$delcompare_sql = "SELECT t1.* from tempdir t1 LEFT JOIN tempdir2 t2 ON t1.id=t2.id WHERE t2.sid is null";$delcompareArr = $conn->query($delcompare_sql);$delcompareRow = $delcompareArr->fetchAll(PDO::FETCH_ASSOC);if(count($delcompareRow)>0){    writeLog("【存在被删除项".count($delcompareRow)."条】");    foreach ($delcompareRow as $key => $value) {        $result_del_1 = $conn->exec("delete from tempdir where id='".$value['id']."'");        $result_delid = $conn->query("select * from transid where oldid='".$value['id']."'");//查询预删除数据在目录树表中对应的id        $row_delid = $result_delid->fetch(PDO::FETCH_ASSOC);        if(!empty($row_delid)){            $result_del_2 = $conn->exec("delete from transid where oldid='".$value['id']."'");            $result_del_3 = $conn->exec("delete from category where cid=".$row_delid['id']);        }    }}//至此 目录树 同步完毕//**********************************************************************************//文件对比//先写入临时对照表writedata($new_filedata,0,'file_compare');//对比新旧文件表$compare_sql = "SELECT t2.*,t1.lastedit as lastedit  from file_compare t2 LEFT JOIN wiki_doc t1 ON t1.oldid=t2.oldid && t2.knowledgeCatalogId=t1.cid && t2.isdeleted=t1.isdeleted && t2.isvisiableForuser=t1.visible && t1.title=t2.title WHERE t1.did is null";$compareArr = $conn->query($compare_sql);$compareRow = $compareArr->fetchAll(PDO::FETCH_ASSOC);if(count($compareRow)>0){    writeLog("【文件表存在差异数据".count($compareRow)."条】");    //********************************************************************************************************    //查询被删除的文件,给领一关联网站发送通知    $delid_arr = array();    foreach ($compareRow as $key => $value) {        if($value['isdeleted']==1){            $delid_arr[] = "'".$value['oldid']."'";        }    }    if(!empty($delid_arr)){        $id_str = implode(",",$delid_arr);        $sel_del_sql = "SELECT oldid from doc WHERE isdeleted=0 and oldid in (".$id_str.")";//对比找出此次被删除的文件        $del_Arr = $conn->query($sel_del_sql);        $del_Row = $del_Arr->fetchAll(PDO::FETCH_ASSOC);        if(!empty($del_Row)){            $report_del_str = '';//已被删除的ID字符串            foreach ($del_Row as $key => $value) {                $report_del_str .= $value['oldid'].",";            }            $report_del_str = substr($report_del_str,0,strlen($report_del_str)-1);            $del_data=array('id' => $report_del_str);            $url_repdel = "url";            $post_del = curl_post_del($url_repdel,$del_data);//发送通知            writeLog("【通知xxx已被删除文件ID,共".count($del_Row)."个,id=".$report_del_str.",".$post_del['reMsg']."】");        }    }    //********************************************************************************************************    //先对关联表进行全部更新    $stmt_add = $conn->prepare("insert into doc (cid,title,summary,author,time,lastedit,lasteditor,visible,isdeleted,oldid) values (:cid,:title,:summary,:author,:time,:lastedit,:lasteditor,:visible,:isdeleted,:oldid)");//插入doc表    $stmt_update = $conn->prepare("update doc set cid=:cid,title=:title,summary=:summary,lastedit=:lastedit,lasteditor=:lasteditor,visible=:visible,isdeleted=:isdeleted where oldid=:oldid");//更新doc表    $stmt_down_url = $conn->prepare("insert into temp_downurl (oid,did,cid,time,filename) values (:oid,:did,:cid,:time,:filename)");    foreach ($compareRow as $key => $value) {        //判断插入还是更新        $result = $conn->query("select did from doc where oldid='".$value['oldid']."'");        $row = $result->fetch(PDO::FETCH_ASSOC);        if(empty($row)){            $arr = array(                ':oldid' => $value['oldid'],                ':cid' => intval($value['knowledgeCatalogId']),                ':title' => $value['title'],                ':summary' => $value['summary'],                ':time' => intval($value['uploadDate']),                ':lastedit' => intval($value['uploadDate']),                ':author' => $value['uploadUserName'],                ':lasteditor' => $value['uploadUserName'],                ':isdeleted' => intval($value['isdeleted']),                ':visible' => intval($value['isvisiableForuser'])            );            $result_add = $stmt_add->execute($arr);            if($result_add>0){                writeLog("【wiki_doc表成功插入oldid=".$value['oldid']."】");            }else{                writeLog("【wiki_doc表插入失败oldid=".$value['oldid']."】");            }            $did = $conn->lastInsertId();            //向预下载表中添加数据            $arr_url = array(                ':oid' => $value['oldid'],                ':did' => intval($did),                ':cid' => intval($value['knowledgeCatalogId']),                ':time' => intval($value['uploadDate']),                ':filename' => $value['title']            );            $result_url = $stmt_down_url->execute($arr_url);            if($result_url>0){                writeLog("【预下载表写入成功did=".$did."】");            }else{                writeLog("【预下载表写入失败did=".$did."】");            }        }else{            $arr = array(                ':oldid' => $value['oldid'],                ':cid' => intval($value['knowledgeCatalogId']),                ':title' => $value['title'],                ':summary' => $value['summary'],                ':lastedit' => intval($value['newUptime']),                ':lasteditor' => $value['uploadUserName'],                ':isdeleted' => intval($value['isdeleted']),                ':visible' => intval($value['isvisiableForuser'])            );            $result_update = $stmt_update->execute($arr);            if($result_update>0){                writeLog("【wiki_doc表修改成功oldid=".$value['oldid']."】");            }else{                writeLog("【wiki_doc表修改失败oldid=".$value['oldid']."】");            }            if($value['lastedit']!==$value['newUptime']){//确定文件重新被上传过                //向预下载表中添加数据                $arr_url = array(                    ':oid' => $value['oldid'],                    ':did' => intval($row['did']),                    ':cid' => intval($value['knowledgeCatalogId']),                    ':time' => intval($value['newUptime']),                    ':filename' => $value['title']                );                $result_url = $stmt_down_url->execute($arr_url);                if($result_url>0){                    writeLog("【预下载表写入成功did=".$row['did']."】");                }else{                    writeLog("【预下载表写入失败did=".$row['did']."】");                }            }        }    }}else{    writeLog("【文件没有新变动】");}//查看link表是否正确对应doc表$compare_sql_link = "SELECT t2.did,t2.cid from doc t2 LEFT JOIN categorylink t1 ON t1.did=t2.did && t2.cid=t1.cid WHERE t1.did is null";$compareArr_link = $conn->query($compare_sql_link);$compareRow_link= $compareArr_link->fetchAll(PDO::FETCH_ASSOC);if(count($compareRow_link)>0){    $stmt_add_link = $conn->prepare("insert into categorylink (did,cid) values (:did,:cid)");//插入link表    $stmt_update_link = $conn->prepare("update categorylink set cid=:cid where did=:did");//插入link表    foreach ($compareRow_link as $key => $value) {        $result = $conn->query("select 1 from categorylink where did='".$value['did']."'");        $row = $result->fetch(PDO::FETCH_ASSOC);        if(empty($row)){            $arr_link = array(                ':did' => intval($value['did']),                ':cid' => intval($value['cid'])            );            $result_add_link = $stmt_add_link->execute($arr_link);            if($result_add_link>0){                writeLog("【插入link表成功did=".$value['did']."】");            }else{                writeLog("【插入link表失败did=".$value['did']."】");            }        }else{            $arr_link = array(                ':did' => intval($value['did']),                ':cid' => intval($value['cid'])            );            $result_update_link = $stmt_update_link->execute($arr_link);            if($result_update_link>0){                writeLog("【修改link表成功did=".$value['did']."】");            }else{                writeLog("【修改link表失败did=".$value['did']."】");            }        }    }}writeLog("【**********************检查更新结束*************************】");echo date("Y-m-d H:i:s")."运行结束\r\n";?>
原创粉丝点击