Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Php Diff Laravel Package

jfcherng/php-diff

Generate diffs between two strings in PHP with multiple renderers: unified/context text, JSON, and rich HTML (inline, side-by-side, combined). Includes configurable differ/renderer options and helper CSS for easy HTML diff styling.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require jfcherng/php-diff
    

    Add to composer.json if using Laravel:

    "require": {
        "jfcherng/php-diff": "^7.0"
    }
    
  2. First Use Case: Compare two strings with the default Unified renderer:

    use Jfcherng\Diff\DiffHelper;
    
    $old = "Hello world!";
    $new = "Hi there!";
    $diff = DiffHelper::calculate($old, $new, 'Unified');
    
  3. Where to Look First:

    • Documentation: README.md (covers all renderers and options).
    • Examples: example/ (practical use cases like file comparisons).
    • API Reference: Class methods in src/ (e.g., Differ, RendererFactory).

Implementation Patterns

Core Workflows

1. String Comparison

// Minimal usage (defaults for DifferOptions/RendererOptions)
$diff = DiffHelper::calculate($oldString, $newString, 'Inline');

// Custom options
$options = new RendererOptions(['detailLevel' => 'word']);
$diff = DiffHelper::calculate($oldString, $newString, 'Inline', null, $options);

2. File Comparison

$diff = DiffHelper::calculateFiles(
    '/path/to/old.txt',
    '/path/to/new.txt',
    'SideBySide'
);

3. JSON Storage + HTML Rendering

// Store JSON in DB
$jsonDiff = DiffHelper::calculate($old, $new, 'Json');
DB::table('diffs')->insert(['content' => $jsonDiff]);

// Later render as HTML
$htmlRenderer = RendererFactory::make('Inline', $rendererOptions);
$htmlDiff = $htmlRenderer->renderArray(json_decode($jsonDiff, true));

4. Custom Renderers

// Extend existing renderers (e.g., for a custom HTML template)
class CustomHtmlRenderer extends \Jfcherng\Diff\Renderer\InlineRenderer {
    protected function renderLine(...): string {
        // Override logic here
    }
}

$renderer = new CustomHtmlRenderer($rendererOptions);

5. Line-by-Line Processing

$differ = new Differ(explode("\n", $old), explode("\n", $new));
$diffLines = $differ->getDiffLines(); // Array of diff operations

Integration Tips

Laravel Blade Integration

// In a controller
public function showDiff() {
    $diff = DiffHelper::calculate($old, $new, 'Inline');
    return view('diff.view', ['diff' => $diff]);
}

// In Blade (diff.view.blade.php)
<div class="diff-container">
    {!! $diff !!}
    @include('diff.styles') <!-- Include DiffHelper::getStyleSheet() -->
</div>

API Responses

return response()->json([
    'diff' => DiffHelper::calculate($old, $new, 'Json'),
    'html' => DiffHelper::calculate($old, $new, 'Inline')
]);

CLI Artisan Commands

// app/Console/Commands/GenerateDiff.php
public function handle() {
    $diff = DiffHelper::calculateFiles(
        storage_path('old.txt'),
        storage_path('new.txt'),
        'Unified'
    );
    $this->info($diff);
}

Testing

public function testDiffGeneration() {
    $diff = DiffHelper::calculate("old", "new", 'Unified');
    $this->assertStringContainsString('-old', $diff);
    $this->assertStringContainsString('+new', $diff);
}

Gotchas and Tips

Pitfalls

  1. HTML Renderer CSS Dependency:

    • HTML renderers (Inline, SideBySide, etc.) require CSS for proper styling.
    • Use DiffHelper::getStyleSheet() or include example/diff-table.css:
      <style>{!! \Jfcherng\Diff\DiffHelper::getStyleSheet() !!}</style>
      
    • Gotcha: Forgetting CSS makes diffs unreadable (e.g., no color highlighting).
  2. Line Ending Sensitivity:

    • By default, ignoreLineEnding: false treats \n vs \r\n as differences.
    • Set ignoreLineEnding: true in DifferOptions to normalize line endings.
  3. Performance with Large Files:

    • lengthLimit in DifferOptions caps input size (default: 2000 chars).
    • For files >2MB, use Context or Unified renderers (faster than HTML renderers).
  4. JSON Renderer Quirks:

    • JsonText vs JsonHtml: JsonHtml escapes HTML tags (e.g., <p> becomes &lt;p&gt;).
    • Use JsonText for raw diff operations, JsonHtml for safe HTML output.
  5. Word/Char-Level Diffs:

    • detailLevel: 'word' or 'char' splits changes granularly but slows processing.
    • Prefer 'line' for most use cases (balance of speed and readability).
  6. Case Sensitivity:

    • ignoreCase: true treats "Hello" and "hello" as identical.
    • Useful for code diffs but may hide semantic changes in text.

Debugging Tips

  1. Inspect Raw Diff Operations:

    $differ = new Differ(explode("\n", $old), explode("\n", $new));
    $diffLines = $differ->getDiffLines();
    dd($diffLines); // Debug the raw diff array
    
  2. Validate JSON Output:

    $jsonDiff = DiffHelper::calculate($old, $new, 'Json');
    $decoded = json_decode($jsonDiff, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        throw new \Exception("Invalid JSON diff");
    }
    
  3. Check Renderer Compatibility:

    • Not all renderers support all detailLevel options (e.g., Combined ignores detailLevel).
    • Test with detailLevel: 'none' if rendering fails.
  4. Handle Empty Diffs:

    • Set fullContextIfIdentical: true in DifferOptions to avoid empty results for identical inputs.

Extension Points

  1. Custom Renderers:

    • Extend \Jfcherng\Diff\Renderer\AbstractRenderer for new formats.
    • Example: Add a MarkdownRenderer for GitHub-style diffs.
  2. Language Support:

    • Override translations via language option in RendererOptions:
      $options = new RendererOptions([
          'language' => [
              'added' => '✅ Added',
              'removed' => '❌ Removed'
          ]
      ]);
      
  3. Pre/Post-Processing:

    • Use Differ::getDiffLines() to modify diff operations before rendering:
      $diffLines = $differ->getDiffLines();
      $diffLines = array_map(function ($chunk) {
          // Filter or transform chunks
          return $chunk;
      }, $diffLines);
      
  4. CLI Colorization:

    • Force colorization for terminal output:
      $options = new RendererOptions([
          'cliColorization' => \Jfcherng\Diff\Renderer\RendererConstant::CLI_COLOR_ENABLE
      ]);
      
  5. Merge Threshold (Combined Renderer):

    • Adjust mergeThreshold to control how aggressively adjacent changes are merged:
      $options = new RendererOptions(['mergeThreshold' => 0.5]); // Merge if <=50% changed
      

Pro Tips

  • For Code Reviews: Use SideBySide with detailLevel: 'word' to highlight inline changes.
  • For APIs: Return JsonText for programmatic diff parsing and Inline for user-facing views.
  • For Localization: Bundle diff-table.css with your app and override colors via CSS variables.
  • For Performance: Cache JSON diffs in Redis if comparing static files (e.g., config backups).
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport