<?php
class diff {
var $changes = array();
var $diff = array();
var $linepadding = null;
function doDiff($old, $new) {
if (!is_array($old))
$old = file($old);
if (!is_array($new))
$new = file($new);
$maxlen = 0;
foreach ($old as $oindex => $ovalue) {
$nkeys = array_keys($new, $ovalue);
foreach ($nkeys as $nindex) {
$matrix[$oindex][$nindex] = isset($matrix[$oindex - 1][$nindex - 1]) ? $matrix[$oindex - 1][$nindex - 1] + 1 : 1;
if ($matrix[$oindex][$nindex] > $maxlen) {
$maxlen = $matrix[$oindex][$nindex];
$omax = $oindex + 1 - $maxlen;
$nmax = $nindex + 1 - $maxlen;
}
}
}
if ($maxlen == 0)
return array(array('d' => $old, 'i' => $new));
return array_merge(
$this->doDiff(array_slice($old, 0, $omax), array_slice($new, 0, $nmax)), array_slice($new, $nmax, $maxlen), $this->doDiff(array_slice($old, $omax + $maxlen), array_slice($new, $nmax + $maxlen)));
}
function diffWrap($old, $new) {
$this->diff = $this->doDiff($old, $new);
$this->changes = array();
$ndiff = array();
foreach ($this->diff as $line => $k) {
if (is_array($k)) {
if (isset($k['d'][0]) || isset($k['i'][0])) {
$this->changes[] = $line;
$ndiff[$line] = $k;
}
} else {
$ndiff[$line] = $k;
}
}
$this->diff = $ndiff;
return $this->diff;
}
function formatcode($code) {
$code = htmlentities($code);
$code = str_replace(" ", ' ', $code);
$code = str_replace("\t", ' ', $code);
return $code;
}
function showline($line) {
if ($this->linepadding === 0) {
if (in_array($line, $this->changes))
return true;
return false;
}
if (is_null($this->linepadding))
return true;
$start = (($line - $this->linepadding) > 0) ? ($line - $this->linepadding) : 0;
$end = ($line + $this->linepadding);
//echo '<br />'.$line.': '.$start.': '.$end;
$search = range($start, $end);
//pr($search);
foreach ($search as $k) {
if (in_array($k, $this->changes))
return true;
}
return false;
}
function inline($old, $new, $linepadding = null) {
// get device details by exloding device path passed over to method
$device_a_pathArr = explode("/", $old);
$device_b_pathArr = explode("/", $new);
// $device_a (Old) details
$device_a_Name = $device_a_pathArr['5'];
$device_a_Date = $device_a_pathArr['8'] . " " . $device_a_pathArr['7'] . " " . $device_a_pathArr['6'];
$device_a_File = $device_a_pathArr['9'];
// $device_b (New) details
$device_b_Name = $device_b_pathArr['5'];
$device_b_Date = $device_b_pathArr['8'] . " " . $device_b_pathArr['7'] . " " . $device_b_pathArr['6'];
$device_b_File = $device_b_pathArr['9'];
$this->linepadding = $linepadding;
$ret = '<pre>
<table width="75%" border="0" cellspacing="0" cellpadding="0" class="code">';
$ret.= '<tr>
<td>Line</td>
<td style="padding-left:20px;"><font size="2"><b>Device:' . $device_a_Name . '</b><font> Date:' . $device_a_Date . ' FileName:' . $device_a_File . ' </td>
<td>Line</td>
<td style="padding-left:20px;"><font size="2"><b>Device:' . $device_b_Name . '</b><font> Date:' . $device_b_Date . ' FileName:' . $device_b_File . ' </td>
</tr>';
$count_old = 1;
$count_new = 1;
$insert = false;
$delete = false;
$truncate = false;
$diff = $this->diffWrap($old, $new);
foreach ($diff as $line => $k) {
if ($this->showline($line)) {
$truncate = false;
if (is_array($k)) {
foreach ($k['d'] as $val) {
$class = '';
if (!$delete) {
$delete = true;
$class = 'first';
if ($insert)
$class = '';
$insert = false;
}
$ret.= '<tr><th>' . $count_old . '</th>';
$ret.= '<td class="del ' . $class . '">' . $this->formatcode($val) . '</td>';
$ret.= '<th> </th>';
$ret.= '<td class="truncated ' . $class . '"> </td>';
$ret.= '</tr>';
$count_old++;
}
foreach ($k['i'] as $val) {
$class = '';
if (!$insert) {
$insert = true;
$class = 'first';
if ($delete)
$class = '';
$delete = false;
}
$ret.= '<tr><th> </th>';
$ret.= '<td class="truncated ' . $class . '"> </td>';
$ret.= '<th>' . $count_new . '</th>';
$ret.= '<td class="ins ' . $class . '">' . $this->formatcode($val) . '</td>';
$ret.= '</tr>';
$count_new++;
}
} else {
$class = ($delete) ? 'del_end' : '';
$class = ($insert) ? 'ins_end' : $class;
$delete = false;
$insert = false;
$ret.= '<tr><th>' . $count_old . '</th>';
$ret.= '<td class="' . $class . '">' . $this->formatcode($k) . '</td>';
$ret.= '<th>' . $count_new . '</th>';
$ret.= '<td class="' . $class . '">' . $this->formatcode($k) . '</td>';
$ret.= '</tr>';
$count_old++;
$count_new++;
}
} else {
$class = ($delete) ? 'del_end' : '';
$class = ($insert) ? 'ins_end' : $class;
$delete = false;
$insert = false;
if (!$truncate) {
$truncate = true;
$ret.= '<tr><th>...</th>';
$ret.= '<td class="truncated ' . $class . '"> </td>';
$ret.= '<th>...</th>';
$ret.= '<td class="truncated ' . $class . '"> </td>';
$ret.= '</tr>';
}
$count_old++;
$count_new++;
}
}
$ret.= '</table></pre>';
return $ret;
}
}
?>
我一直在阅读关于php中的gabarge集合,但是现在一切看起来有点令人困惑。上面的脚本共同编写了2个文件的差异,并且对于小于168kb的文件来说它的工作正常......我有一个168 kb的大文件,当你尝试比较2个文件时,它会抱怨内存耗尽。试图增加php.ini中的内存,直到它大约1000M,对我来说,这似乎是一个写得不好的代码......你能帮我优化吗