📄 history2.php
字号:
<?php//$lang checkeddefined('WikyBlog') or die("Not an entry point...");///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// difference_main//class difference_main{ var $instructions; var $keys; var $differences = 0; function difference_main($source,$result){ $instruction = array(); // 1) if Objects => arrays if( is_object($result) ){ $type = get_class( $result ); $type2 = get_class( $source ); if( $type !== $type2){ trigger_error('Objects are not of the same type '.$type.' :: '.$type2); } $source = get_object_vars( $source ); $result = get_object_vars( $result ); } // 2) Make instructions for each field $workingClass = new getInstructions(); foreach($result as $key => $resultValue){ $sourceValue = $source[$key]; if( empty($resultValue) ){ $resultValue = ''; } if( empty($sourceValue) ){ $sourceValue = ''; } $workingClass->calcDifference($sourceValue, $resultValue); $workingClass->setInstructions(); if( isset($workingClass->instructions) ){ $instructions[$key] = $workingClass->instructions; $this->keys[] = $key; $this->differences += $workingClass->differences; } } // 3) Serialize, Compress and return if( !empty($instructions) ){ //echo showArray($instructions); $instructions = serialize($instructions); $this->instructions = $instructions; if( function_exists('gzdeflate') ){ $this->instructions = gzdeflate($this->instructions); } } } }//// difference_main/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// difference// class difference{ //////////////////////////////////////////////////////////////////////////// //// //// VARIABLES //// var $source; var $result; var $left; var $leftIndex; var $maxleft; var $right; var $rightIndex; var $maxRight; var $deleteLeft; var $addRight; var $instructions; var $debugText; var $differences; function resetVars(){ $array = get_class_vars( get_class($this) ); foreach($array as $key => $value){ unset($this->$key); } //$this->differences = 0; $this->leftIndex = 0; $this->rightIndex = 0; $this->deleteLeft = array(); $this->addRight = array(); } //////////////////////////////////////////////////////////////////////////// //// //// This Does the Work //// $left = source; $right = result; //// function calcDifference($left,$right,$doBlankLines=true){ // 0) don't bother getting instructions if result is very small // this doesn't exactly work because of later comparison... // if( wbStrlen($right) < 80 ){// $this->instructions = $right;// return;// } $this->resetVars(); $this->source = $left; $this->result = $right; $this->left = stringToArray($left); $this->right = stringToArray($right); $this->maxLeft = count($this->left); $this->maxRight = count($this->right); /// should use a foreach(..) here... I think they're faster too while( ($this->leftIndex < $this->maxLeft) or ($this->rightIndex < $this->maxRight) ){ //echo $this->debugText; //$this->debugText = '<p>'; //////////////////////////////////////////////////////////////////////////// //// //// I) End of left or right //// // left at max if( $this->leftIndex == $this->maxLeft ){ //$this->debugText .= '<p>LeftIndex = max = '.$this->maxLeft; while($this->rightIndex < $this->maxRight){ $this->addRight(); } break; } // right at max if( $this->rightIndex == $this->maxRight ){ //$this->debugText .= '<p>RightIndex = max = '.$this->maxRight; while($this->leftIndex < $this->maxLeft){ $this->deleteLeft(); } break; } //////////////////////////////////////////////////////////////////////////// //// //// II) left == right //// if( $this->left[$this->leftIndex] == $this->right[$this->rightIndex] ){ //$this->debugText .= '<p>Equal at left: '.$this->leftIndex.' Right: '.$this->rightIndex; unset($this->left[$this->leftIndex]); unset($this->right[$this->rightIndex]); $this->leftIndex++; $this->rightIndex++; continue; } //////////////////////////////////////////////////////////////////////////// //// //// III) left != right //// if($doBlankLines){ // 2) Add or Delete Blank Lines if( empty($this->left[$this->leftIndex]) || $this->left[$this->leftIndex] == ''){ //$this->debugText .= '<br><b>Empty line on left at</b> '.$this->leftIndex; $this->deleteLeft(); continue; } if( empty($this->right[$this->rightIndex]) || $this->right[$this->rightIndex] == ''){ //$this->debugText .= '<br><b>Empty line on right at</b> '.$this->rightIndex; $this->addRight(); continue; } } // 3) Distance to next similarity $rightMatchAt = false; $leftMatchAt = false; $rightMatchAt = array_search($this->left[$this->leftIndex],$this->right); $leftMatchAt = array_search($this->right[$this->rightIndex],$this->left); //$this->debugText .= '<p>Left: '.$this->leftIndex. ' Right-Match At: '.$rightMatchAt .' Right: '.$this->rightIndex. ' Left-Match at: '.$leftMatchAt; // 4) left never equals right with either line: // - this should prevent both differences from being negative below if( ($rightMatchAt === false) && ($leftMatchAt === false)){ $this->addRight(); $this->deleteLeft(); continue; } if($rightMatchAt === false){ $this->deleteLeft(); continue; } if($leftMatchAt === false){ $this->addRight(); continue; } $numAdds = ($rightMatchAt - $this->rightIndex); $numDeletes = ($leftMatchAt - $this->leftIndex);; //$this->debugText .= '<br> Number of Adds: '.$numAdds; //$this->debugText .= '<br> Number of Deletes: '.$numDeletes; if( (($numAdds>0) && ($numAdds<=$numDeletes)) || ($numDeletes<0) ){ while($this->rightIndex < $rightMatchAt){ $this->addRight(); } }elseif($numDeletes >= 0){ while($this->leftIndex < $leftMatchAt){ $this->deleteLeft(); } } }// 1st while //echo $this->debugText; $this->differences = $this->numberOfDifferences(); return; }//end function findDifference function addRight(){ //$this->debugText .= '<br> Add right: (leftIndex) '.$this->leftIndex; $this->addRight[$this->leftIndex][$this->rightIndex] = $this->right[$this->rightIndex]; unset($this->right[$this->rightIndex]); $this->rightIndex++; //$this->differences++; } function deleteLeft(){ //$this->debugText .= '<br> Delete left: (leftIndex) '.$this->leftIndex; $this->deleteLeft[$this->leftIndex] = $this->left[$this->leftIndex]; unset($this->left[$this->leftIndex]); $this->leftIndex++; //$this->differences++; } function numberOfDifferences(){ $differences = 0; $temp1 = array_keys($this->deleteLeft); $temp2 = array_keys($this->addRight); $intersection = count( array_intersect($temp1,$temp2) ); $differences = count($this->deleteLeft) + (count($this->addRight,1)-count($this->addRight) ); $differences -= $intersection; return $differences; } }//// difference/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// getInstructions// translates add/delete then serializesclass getInstructions extends difference{ function setInstructions(){ if( empty($this->deleteLeft) && empty($this->addRight) ){ return; } // 1) Make Move Instructions $deleteTemp = $this->deleteLeft; $addTemp = $this->addRight; $moveTemp = NULL; foreach($this->addRight as $leftIndex => $addArray){ foreach($addArray as $rightIndex => $addLine){ if( ($addLine == '') || empty($addLine)){ continue; } $moveFrom = false; $moveFrom = array_search($addLine,$deleteTemp); if( $moveFrom !== false){ $moveTemp[$moveFrom]=$leftIndex.'.'.$rightIndex; unset($deleteTemp[$moveFrom]); unset($addTemp[$leftIndex][$rightIndex]); } } } if( !empty($moveTemp) ){ $array['m'] = $moveTemp; } // 2) Replace Instructions $replaceTemp = array(); foreach($deleteTemp as $leftIndex => $deleteLine){ if( isset($addTemp[$leftIndex]) ){ foreach($addTemp[$leftIndex] as $addKey => $addLine){ $replaceTemp[$leftIndex][$addKey] = $addLine; //$replaceTemp[$leftIndex] = $addLine; // other options for saving space? only a few bytes here and there //$replaceTemp[$leftIndex.'.'.$addKey] = $addLine; // } unset($addTemp[$leftIndex]); unset($deleteTemp[$leftIndex]); } } if( !empty($replaceTemp) ){ $array['r'] = $replaceTemp; } // 3) Compress Delete Instrucions foreach($deleteTemp as $key => $deleteLine){ $array['d'][$key] = ''; } // 4) Add instructions if( !empty($addTemp) ){ $array['a'] = $addTemp; } // 5) Check Size of instructions vs just saving value if( function_exists('gzdeflate') ){ $resultSize = strlen(gzdeflate($this->result)); $instructionSize = strlen(gzdeflate( serialize($array) )); }else{ $resultSize = $this->result; $instructionSize = strlen(serialize($array)); } // echo '<p><b>Sizes</b> (compressed)'; // echo '<br>Result Size: '.$resultSize; // echo '<br>Size of Instructions: '.$instructionSize; if($resultSize <= $instructionSize){ $this->instructions = $this->result; }else{ $this->instructions = $array; } }// end setInstructions}//// getInstructions////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -