src/Diff.php
public function main($text1, $text2, $checklines = true, $deadline = null)
    {
        // Set a deadline by which time the diff must be complete.
        if (!isset($deadline)) {
            if ($this->getTimeout() <= 0) {
                $deadline  = PHP_INT_MAX;
            } else {
                $deadline = microtime(1) + $this->getTimeout();
            }
        }

        if (!isset($text1, $text2)) {
            throw new \InvalidArgumentException();
        }

        // Check for equality (speedup).
        if ($text1 == $text2) {
            if ($text1 != '') {
                $this->setChanges(array(
                    array(self::EQUAL, $text1),
                ));
                return $this;
            }
            return $this;
        }

        $prevInternalEncoding = mb_internal_encoding();
        $newInternalEncoding = 'UCS-2LE';
        if ($prevInternalEncoding != $newInternalEncoding) {
            mb_internal_encoding($newInternalEncoding);

            $errorReportingLevel = error_reporting();
            error_reporting($errorReportingLevel & ~E_NOTICE);

            $text1Draft = iconv($prevInternalEncoding, $newInternalEncoding, $text1);
            $text2Draft = iconv($prevInternalEncoding, $newInternalEncoding, $text2);

            if ($text1Draft === false || $text2Draft === false) {
                $newInternalEncoding = 'UCS-4LE';

                $text1Draft = iconv($prevInternalEncoding, $newInternalEncoding, $text1);
                $text2Draft = iconv($prevInternalEncoding, $newInternalEncoding, $text2);
            }

            $text1 = $text1Draft;
            $text2 = $text2Draft;

            error_reporting($errorReportingLevel);
        }

        // Trim off common prefix (speedup).
        $commonLength = $this->getToolkit()->commonPrefix($text1, $text2);
        if ($commonLength == 0) {
            $commonPrefix = '';
        } else {
            $commonPrefix = mb_substr($text1, 0, $commonLength);
            $text1 = mb_substr($text1, $commonLength);
            $text2 = mb_substr($text2, $commonLength);
        }

        // Trim off common suffix (speedup).
        $commonLength = $this->getToolkit()->commonSuffix($text1, $text2);
        if ($commonLength == 0) {
            $commonSuffix = '';
        } else {
            $commonSuffix = mb_substr($text1, -$commonLength);
            $text1 = mb_substr($text1, 0, -$commonLength);
            $text2 = mb_substr($text2, 0, -$commonLength);
        }

        // Compute the diff on the middle block.
        $diffs = $this->compute($text1, $text2, $checklines, $deadline);

        // Restore the prefix and suffix.
        if ($commonPrefix != '') {
            array_unshift($diffs, array(self::EQUAL, $commonPrefix));
        }
        if ($commonSuffix != '') {
            array_push($diffs, array(self::EQUAL, $commonSuffix));
        }

        if ($newInternalEncoding != $prevInternalEncoding) {
            mb_internal_encoding($prevInternalEncoding);
            foreach ($diffs as &$change) {
                $change[1] = iconv($newInternalEncoding, $prevInternalEncoding, $change[1]);
            }
            unset($change);
        }

        $this->setChanges($diffs);

        $this->cleanupMerge();

        return $this;
    }
public function main($text1, $text2, $checklines = true, $deadline = null)
    {
        // Set a deadline by which time the diff must be complete.
        if (!isset($deadline)) {
            if ($this->getTimeout() <= 0) {
                $deadline  = PHP_INT_MAX;
            } else {
                $deadline = microtime(1) + $this->getTimeout();
            }
        }

        if (!isset($text1, $text2)) {
            throw new \InvalidArgumentException();
        }

        // Check for equality (speedup).
        if ($text1 == $text2) {
            if ($text1 != '') {
                $this->setChanges(array(
                    array(self::EQUAL, $text1),
                ));
                return $this;
            }
            return $this;
        }

        $prevInternalEncoding = mb_internal_encoding();
        $newInternalEncoding = 'UCS-2LE';
        if ($prevInternalEncoding != $newInternalEncoding) {
            mb_internal_encoding($newInternalEncoding);

            $errorReportingLevel = error_reporting();
            error_reporting($errorReportingLevel & ~E_NOTICE);

            $text1Draft = iconv($prevInternalEncoding, $newInternalEncoding, $text1);
            $text2Draft = iconv($prevInternalEncoding, $newInternalEncoding, $text2);

            if ($text1Draft === false || $text2Draft === false) {
                $newInternalEncoding = 'UCS-4LE';

                $text1Draft = iconv($prevInternalEncoding, $newInternalEncoding, $text1);
                $text2Draft = iconv($prevInternalEncoding, $newInternalEncoding, $text2);
            }

            $text1 = $text1Draft;
            $text2 = $text2Draft;

            error_reporting($errorReportingLevel);
        }

        // Trim off common prefix (speedup).
        $commonLength = $this->getToolkit()->commonPrefix($text1, $text2);
        if ($commonLength == 0) {
            $commonPrefix = '';
        } else {
            $commonPrefix = mb_substr($text1, 0, $commonLength);
            $text1 = mb_substr($text1, $commonLength);
            $text2 = mb_substr($text2, $commonLength);
        }

        // Trim off common suffix (speedup).
        $commonLength = $this->getToolkit()->commonSuffix($text1, $text2);
        if ($commonLength == 0) {
            $commonSuffix = '';
        } else {
            $commonSuffix = mb_substr($text1, -$commonLength);
            $text1 = mb_substr($text1, 0, -$commonLength);
            $text2 = mb_substr($text2, 0, -$commonLength);
        }

        // Compute the diff on the middle block.
        $diffs = $this->compute($text1, $text2, $checklines, $deadline);

        // Restore the prefix and suffix.
        if ($commonPrefix != '') {
            array_unshift($diffs, array(self::EQUAL, $commonPrefix));
        }
        if ($commonSuffix != '') {
            array_push($diffs, array(self::EQUAL, $commonSuffix));
        }

        if ($newInternalEncoding != $prevInternalEncoding) {
            mb_internal_encoding($prevInternalEncoding);
            foreach ($diffs as &$change) {
                $change[1] = iconv($newInternalEncoding, $prevInternalEncoding, $change[1]);
            }
            unset($change);
        }

        $this->setChanges($diffs);

        $this->cleanupMerge();

        return $this;
    }
Find the differences between two texts.  Simplifies the problem by
stripping any common prefix or suffix off the texts before diffing.

@param string $text1      Old string to be diffed.
@param string $text2      New string to be diffed.
@param bool   $checklines Optional speedup flag.  If present and false, then don't run
a line-level diff first to identify the changed areas.
Defaults to true, which does a faster, slightly less optimal diff.
@param int    $deadline   Optional time when the diff should be complete by.  Used internally for recursive calls.
Users should set $this->timeout instead.

@throws \InvalidArgumentException If texts is null. TODO create exception class
@return self