您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <?php
  2. /**
  3. * Diff
  4. *
  5. * A comprehensive library for generating differences between two strings
  6. * in multiple formats (unified, side by side HTML etc)
  7. *
  8. * PHP version 5
  9. *
  10. * Copyright (c) 2009 Chris Boulton <chris.boulton@interspire.com>
  11. *
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions are met:
  16. *
  17. * - Redistributions of source code must retain the above copyright notice,
  18. * this list of conditions and the following disclaimer.
  19. * - Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. * - Neither the name of the Chris Boulton nor the names of its contributors
  23. * may be used to endorse or promote products derived from this software
  24. * without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  27. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  30. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  31. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  32. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  34. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  35. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. * POSSIBILITY OF SUCH DAMAGE.
  37. *
  38. * @package Diff
  39. * @author Chris Boulton <chris.boulton@interspire.com>
  40. * @copyright (c) 2009 Chris Boulton
  41. * @license New BSD License http://www.opensource.org/licenses/bsd-license.php
  42. * @version 1.1
  43. * @link http://github.com/chrisboulton/php-diff
  44. */
  45. class Diff
  46. {
  47. /**
  48. * @var array The "old" sequence to use as the basis for the comparison.
  49. */
  50. private $a = null;
  51. /**
  52. * @var array The "new" sequence to generate the changes for.
  53. */
  54. private $b = null;
  55. /**
  56. * @var array Array containing the generated opcodes for the differences between the two items.
  57. */
  58. private $groupedCodes = null;
  59. /**
  60. * @var array Associative array of the default options available for the diff class and their default value.
  61. */
  62. private $defaultOptions = array(
  63. 'context' => 3,
  64. 'ignoreNewLines' => false,
  65. 'ignoreWhitespace' => false,
  66. 'ignoreCase' => false
  67. );
  68. /**
  69. * @var array Array of the options that have been applied for generating the diff.
  70. */
  71. private $options = array();
  72. /**
  73. * The constructor.
  74. *
  75. * @param array $a Array containing the lines of the first string to compare.
  76. * @param array $b Array containing the lines for the second string to compare.
  77. * @param array $options
  78. */
  79. public function __construct($a, $b, $options=array())
  80. {
  81. $this->a = $a;
  82. $this->b = $b;
  83. $this->options = array_merge($this->defaultOptions, $options);
  84. }
  85. /**
  86. * Render a diff using the supplied rendering class and return it.
  87. *
  88. * @param Diff_Renderer_Abstract $renderer An instance of the rendering object to use for generating the diff.
  89. * @return mixed The generated diff. Exact return value depends on the rendered.
  90. */
  91. public function render(Diff_Renderer_Abstract $renderer)
  92. {
  93. $renderer->diff = $this;
  94. return $renderer->render();
  95. }
  96. /**
  97. * Get a range of lines from $start to $end from the first comparison string
  98. * and return them as an array. If no values are supplied, the entire string
  99. * is returned. It's also possible to specify just one line to return only
  100. * that line.
  101. *
  102. * @param int $start The starting number.
  103. * @param int $end The ending number. If not supplied, only the item in $start will be returned.
  104. * @return array Array of all of the lines between the specified range.
  105. */
  106. public function getA($start=0, $end=null)
  107. {
  108. if($start == 0 && $end === null) {
  109. return $this->a;
  110. }
  111. if($end === null) {
  112. $length = 1;
  113. }
  114. else {
  115. $length = $end - $start;
  116. }
  117. return array_slice($this->a, $start, $length);
  118. }
  119. /**
  120. * Get a range of lines from $start to $end from the second comparison string
  121. * and return them as an array. If no values are supplied, the entire string
  122. * is returned. It's also possible to specify just one line to return only
  123. * that line.
  124. *
  125. * @param int $start The starting number.
  126. * @param int $end The ending number. If not supplied, only the item in $start will be returned.
  127. * @return array Array of all of the lines between the specified range.
  128. */
  129. public function getB($start=0, $end=null)
  130. {
  131. if($start == 0 && $end === null) {
  132. return $this->b;
  133. }
  134. if($end === null) {
  135. $length = 1;
  136. }
  137. else {
  138. $length = $end - $start;
  139. }
  140. return array_slice($this->b, $start, $length);
  141. }
  142. /**
  143. * Generate a list of the compiled and grouped opcodes for the differences between the
  144. * two strings. Generally called by the renderer, this class instantiates the sequence
  145. * matcher and performs the actual diff generation and return an array of the opcodes
  146. * for it. Once generated, the results are cached in the diff class instance.
  147. *
  148. * @return array Array of the grouped opcodes for the generated diff.
  149. */
  150. public function getGroupedOpcodes()
  151. {
  152. if(!is_null($this->groupedCodes)) {
  153. return $this->groupedCodes;
  154. }
  155. require_once dirname(__FILE__).'/Diff/SequenceMatcher.php';
  156. $sequenceMatcher = new Diff_SequenceMatcher($this->a, $this->b, null, $this->options);
  157. $this->groupedCodes = $sequenceMatcher->getGroupedOpcodes();
  158. return $this->groupedCodes;
  159. }
  160. }