⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diff.inc.php

📁 简介:IceBB是一个强大
💻 PHP
📖 第 1 页 / 共 3 页
字号:
<?php// This file is licensed under the LGPL and is from the Text_Diff PEAR project which// is available at http://pear.php.net/package/Text_Diff/** * Text_Diff * * General API for generating and formatting diffs - the differences between * two sequences of strings. * * The PHP diff code used in this package was originally written by Geoffrey * T. Dairiki and is used with his permission. * * $Horde: framework/Text_Diff/Diff.php,v 1.10 2004/11/01 11:51:15 mdjukic Exp $ * * @package Text_Diff * @author  Geoffrey T. Dairiki <dairiki@dairiki.org> */class Text_Diff {    /**     * Array of changes.     *     * @var array $_edits     */    var $_edits;    /**     * Computes diffs between sequences of strings.     *     * @param array $from_lines  An array of strings.  Typically these are     *                           lines from a file.     * @param array $to_lines    An array of strings.     */    function Text_Diff($from_lines, $to_lines)    {        array_walk($from_lines, array($this, '_trimNewlines'));        array_walk($to_lines, array($this, '_trimNewlines'));        if (extension_loaded('xdiff')) {            $engine = &new Text_Diff_Engine_xdiff();        } else {            $engine = &new Text_Diff_Engine_native();        }        $this->_edits = $engine->diff($from_lines, $to_lines);    }    /**     * Returns the array of differences.     */    function getDiff()    {        return $this->_edits;    }    /**     * Computes a reversed diff.     *     * Example:     * <code>     * $diff = &new Text_Diff($lines1, $lines2);     * $rev = $diff->reverse();     * </code>     *     * @return Text_Diff  A Diff object representing the inverse of the     *                    original diff.  Note that we purposely don't return a     *                    reference here, since this essentially is a clone()     *                    method.     */    function reverse()    {        if (version_compare(zend_version(), '2', '>')) {            $rev = clone($obj);        } else {            $rev = $this;        }        $rev->_edits = array();        foreach ($this->_edits as $edit) {            $rev->_edits[] = $edit->reverse();        }        return $rev;    }    /**     * Checks for an empty diff.     *     * @return boolean  True if two sequences were identical.     */    function isEmpty()    {        foreach ($this->_edits as $edit) {            if (!is_a($edit, 'Text_Diff_Op_copy')) {                return false;            }        }        return true;    }    /**     * Computes the length of the Longest Common Subsequence (LCS).     *     * This is mostly for diagnostic purposed.     *     * @return int  The length of the LCS.     */    function lcs()    {        $lcs = 0;        foreach ($this->_edits as $edit) {            if (is_a($edit, 'Text_Diff_Op_copy')) {                $lcs += count($edit->orig);            }        }        return $lcs;    }    /**     * Gets the original set of lines.     *     * This reconstructs the $from_lines parameter passed to the constructor.     *     * @return array  The original sequence of strings.     */    function getOriginal()    {        $lines = array();        foreach ($this->_edits as $edit) {            if ($edit->orig) {                array_splice($lines, count($lines), 0, $edit->orig);            }        }        return $lines;    }    /**     * Gets the final set of lines.     *     * This reconstructs the $to_lines parameter passed to the constructor.     *     * @return array  The sequence of strings.     */    function getFinal()    {        $lines = array();        foreach ($this->_edits as $edit) {            if ($edit->final) {                array_splice($lines, count($lines), 0, $edit->final);            }        }        return $lines;    }    /**     * Removes trailing newlines from a line of text. This is meant to be used     * with array_walk().     *     * @param string $line  The line to trim.     * @param integer $key  The index of the line in the array. Not used.     */    function _trimNewlines(&$line, $key)    {        $line = str_replace(array("\n", "\r"), '', $line);    }    /**     * Checks a diff for validity.     *     * This is here only for debugging purposes.     */    function _check($from_lines, $to_lines)    {        if (serialize($from_lines) != serialize($this->getOriginal())) {            trigger_error("Reconstructed original doesn't match", E_USER_ERROR);        }        if (serialize($to_lines) != serialize($this->getFinal())) {            trigger_error("Reconstructed final doesn't match", E_USER_ERROR);        }        $rev = $this->reverse();        if (serialize($to_lines) != serialize($rev->getOriginal())) {            trigger_error("Reversed original doesn't match", E_USER_ERROR);        }        if (serialize($from_lines) != serialize($rev->getFinal())) {            trigger_error("Reversed final doesn't match", E_USER_ERROR);        }        $prevtype = null;        foreach ($this->_edits as $edit) {            if ($prevtype == get_class($edit)) {                trigger_error("Edit sequence is non-optimal", E_USER_ERROR);            }            $prevtype = get_class($edit);        }        return true;    }}/** * $Horde: framework/Text_Diff/Diff.php,v 1.10 2004/11/01 11:51:15 mdjukic Exp $ * * @package Text_Diff * @author  Geoffrey T. Dairiki <dairiki@dairiki.org> */class Text_MappedDiff extends Text_Diff {    /**     * Computes a diff between sequences of strings.     *     * This can be used to compute things like case-insensitve diffs, or diffs     * which ignore changes in white-space.     *     * @param array $from_lines         An array of strings.     * @param array $to_lines           An array of strings.     * @param array $mapped_from_lines  This array should have the same size     *                                  number of elements as $from_lines.  The     *                                  elements in $mapped_from_lines and     *                                  $mapped_to_lines are what is actually     *                                  compared when computing the diff.     * @param array $mapped_to_lines    This array should have the same number     *                                  of elements as $to_lines.     */    function Text_MappedDiff($from_lines, $to_lines,                             $mapped_from_lines, $mapped_to_lines)    {        assert(count($from_lines) == count($mapped_from_lines));        assert(count($to_lines) == count($mapped_to_lines));        parent::Text_Diff($mapped_from_lines, $mapped_to_lines);        $xi = $yi = 0;        for ($i = 0; $i < count($this->_edits); $i++) {            $orig = &$this->_edits[$i]->orig;            if (is_array($orig)) {                $orig = array_slice($from_lines, $xi, count($orig));                $xi += count($orig);            }            $final = &$this->_edits[$i]->final;            if (is_array($final)) {                $final = array_slice($to_lines, $yi, count($final));                $yi += count($final);            }        }    }}/** * Class used internally by Diff to actually compute the diffs.  This class * uses the xdiff PECL package (http://pecl.php.net/package/xdiff) to compute * the differences between the two input arrays. * * @author  Jon Parise <jon@horde.org> * @package Text_Diff * @access  private */class Text_Diff_Engine_xdiff {    function diff($from_lines, $to_lines)    {        /* Convert the two input arrays into strings for xdiff processing. */        $from_string = implode("\n", $from_lines);        $to_string = implode("\n", $to_lines);        /* Diff the two strings and convert the result to an array. */        $diff = xdiff_string_diff($from_string, $to_string, count($to_lines));        $diff = explode("\n", $diff);        /* Walk through the diff one line at a time.  We build the $edits         * array of diff operations by reading the first character of the         * xdiff output (which is in the "unified diff" format).         *         * Note that we don't have enough information to detect "changed"         * lines using this approach, so we can't add Text_Diff_Op_changed         * instances to the $edits array.  The result is still perfectly         * valid, albeit a little less descriptive and efficient. */        $edits = array();        foreach ($diff as $line) {            switch ($line[0]) {            case ' ':                $edits[] = &new Text_Diff_Op_copy(array(substr($line, 1)));                break;            case '+':                $edits[] = &new Text_Diff_Op_add(array(substr($line, 1)));                break;            case '-':                $edits[] = &new Text_Diff_Op_delete(array(substr($line, 1)));                break;            }        }        return $edits;    }}/** * Class used internally by Diff to actually compute the diffs.  This class is * implemented using native PHP code. * * The algorithm used here is mostly lifted from the perl module * Algorithm::Diff (version 1.06) by Ned Konz, which is available at: * http://www.perl.com/CPAN/authors/id/N/NE/NEDKONZ/Algorithm-Diff-1.06.zip * * More ideas are taken from: * http://www.ics.uci.edu/~eppstein/161/960229.html * * Some ideas (and a bit of code) are from from analyze.c, from GNU * diffutils-2.7, which can be found at: * ftp://gnudist.gnu.org/pub/gnu/diffutils/diffutils-2.7.tar.gz * * Some ideas (subdivision by NCHUNKS > 2, and some optimizations) are from * Geoffrey T. Dairiki <dairiki@dairiki.org>. The original PHP version of this * code was written by him, and is used/adapted with his permission. * * @author  Geoffrey T. Dairiki <dairiki@dairiki.org> * @package Text_Diff * @access  private */class Text_Diff_Engine_native {    function diff($from_lines, $to_lines)    {        $n_from = count($from_lines);        $n_to = count($to_lines);        $this->xchanged = $this->ychanged = array();        $this->xv = $this->yv = array();        $this->xind = $this->yind = array();        unset($this->seq);        unset($this->in_seq);        unset($this->lcs);        // Skip leading common lines.        for ($skip = 0; $skip < $n_from && $skip < $n_to; $skip++) {            if ($from_lines[$skip] != $to_lines[$skip]) {                break;            }            $this->xchanged[$skip] = $this->ychanged[$skip] = false;        }        // Skip trailing common lines.        $xi = $n_from; $yi = $n_to;        for ($endskip = 0; --$xi > $skip && --$yi > $skip; $endskip++) {            if ($from_lines[$xi] != $to_lines[$yi]) {                break;            }            $this->xchanged[$xi] = $this->ychanged[$yi] = false;        }        // Ignore lines which do not exist in both files.        for ($xi = $skip; $xi < $n_from - $endskip; $xi++) {            $xhash[$from_lines[$xi]] = 1;        }        for ($yi = $skip; $yi < $n_to - $endskip; $yi++) {            $line = $to_lines[$yi];            if (($this->ychanged[$yi] = empty($xhash[$line]))) {                continue;            }            $yhash[$line] = 1;            $this->yv[] = $line;            $this->yind[] = $yi;        }        for ($xi = $skip; $xi < $n_from - $endskip; $xi++) {            $line = $from_lines[$xi];            if (($this->xchanged[$xi] = empty($yhash[$line]))) {                continue;            }            $this->xv[] = $line;            $this->xind[] = $xi;        }        // Find the LCS.        $this->_compareseq(0, count($this->xv), 0, count($this->yv));        // Merge edits when possible.        $this->_shiftBoundaries($from_lines, $this->xchanged, $this->ychanged);        $this->_shiftBoundaries($to_lines, $this->ychanged, $this->xchanged);        // Compute the edit operations.        $edits = array();        $xi = $yi = 0;        while ($xi < $n_from || $yi < $n_to) {            assert($yi < $n_to || $this->xchanged[$xi]);            assert($xi < $n_from || $this->ychanged[$yi]);            // Skip matching "snake".            $copy = array();            while ($xi < $n_from && $yi < $n_to                   && !$this->xchanged[$xi] && !$this->ychanged[$yi]) {                $copy[] = $from_lines[$xi++];                ++$yi;            }            if ($copy) {                $edits[] = &new Text_Diff_Op_copy($copy);            }            // Find deletes & adds.            $delete = array();            while ($xi < $n_from && $this->xchanged[$xi]) {                $delete[] = $from_lines[$xi++];            }            $add = array();            while ($yi < $n_to && $this->ychanged[$yi]) {                $add[] = $to_lines[$yi++];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -