PHP Classes

pharaoh: Compare two PHAR files to retrieve the differences

Recommend this page to a friend!
     
  Info   Example   View files Files   Install with Composer Install with Composer   Download Download   Reputation   Support forum   Blog    
Ratings Unique User Downloads Download Rankings
Not yet rated by the usersTotal: 43 All time: 10,838 This week: 206Up
Version License PHP version Categories
pharaoh 1.0.0MIT/X Consortium ...5PHP 5, Tools, Files and Folders, Parsers
Description 

Author

This package can compare two PHAR files to retrieve the differences.

It can take two PHAR archive files and inspects them to check what are the differences between them.

The package can output the differences between the two packages in several ways like:

- Differences between the source files they contain
- Contained files that have different content hashes

Innovation Award
PHP Programming Innovation award nominee
March 2019
Number 3
PHAR is a file format used to package components made of many files, so they can be easily loaded and distributed with different PHP applications.

This package can compare and show the differences between two PHAR archives in terms of the files that they contain and and they file contents.

Manuel Lemos
Picture of Scott Arciszewski
  Performance   Level  
Name: Scott Arciszewski <contact>
Classes: 37 packages by
Country: United States United States
Age: ???
All time rank: 1173170 in United States United States
Week rank: 164 Up23 in United States United States Up
Innovation award
Innovation award
Nominee: 28x

Winner: 1x

Example

<?php
declare(strict_types=1);

require_once \
dirname(__DIR__) . '/vendor/autoload.php';
$opts = \getopt('gdrpcv::', [
   
'git-diff', 'diff', 'report', 'pdf', 'check::', 'verbose'
]);

if (
$argc < 3) {
    die(
"Please pass two phars to diff them.\n");
}

// The last two commands should be our two .phar files
/** @var string $pharB */
$pharB = \array_pop($argv);
/** @var string $pharA */
$pharA = \array_pop($argv);

$phars = [
    new \
ParagonIE\Pharaoh\Pharaoh($pharA),
    new \
ParagonIE\Pharaoh\Pharaoh($pharB)
];

$diff = new \ParagonIE\Pharaoh\PharDiff($phars[0], $phars[1]);

if (!empty(
$opts['v']) || !empty($opts['verbose'])) {
   
$diff->setVerbose(true);
}

if (!empty(
$opts['c'])) {
   
$return = $diff->listChecksums($opts['c']);
} elseif (!empty(
$opts['check'])) {
   
$return = $diff->listChecksums($opts['check']);
} elseif (isset(
$opts['d']) || isset($opts['diff'])) {
   
$return = $diff->printGnuDiff();
} else {
   
$return = $diff->printGitDiff();
}
exit(
$return);


Details

Pharaoh - PHAR diff utility

Build Status Latest Stable Version Latest Unstable Version License

Display the differences between all of the files in two PHP Archives.

In all likelihood, two PHP Archives will not be byte-for-byte compatible, so sha256sum will not yield the same result, even if they were both built from the same source code and contain the same contents. This is because Composer randomizes e.g. their autoloader class names.

Copyright (c) 2015 - 2018 Paragon Initiative Enterprises. Check out our other open source projects too.

Pharaoh is used by Box to provide diffs.

Example

To verify two PHP Archives were built from the same source code, first download the official distribution and then build a Phar from source.

Basic Usage

To see what differs between the two files, run this command:

/path/to/pharaoh \
    /path/to/distributed.phar \
    /path/to/built-from-source-code.phar

Sample output:

$ pharaoh dist/sodium-compat-php5.phar dist/sodium-compat-php7.phar
diff --git a/tmp/phr_GPrhh5/vendor/autoload.php b/tmp/phr_SBYnr7/vendor/autoload.php
index c20d4db..5c849e0 100644
--- a/tmp/phr_GPrhh5/vendor/autoload.php
+++ b/tmp/phr_SBYnr7/vendor/autoload.php
@@ -4,4 +4,4 @@
 
 require_once __DIR__ . '/composer/autoload_real.php';
 
-return ComposerAutoloaderInitf6d95af9246e0e0e98e255e3bc14c82b::getLoader();
+return ComposerAutoloaderInitd4c7400998bd39c407a1d41a47cd86c6::getLoader();
diff --git a/tmp/phr_GPrhh5/vendor/composer/autoload_real.php b/tmp/phr_SBYnr7/vendor/composer/autoload_real.php
index a23d814..432c698 100644
--- a/tmp/phr_GPrhh5/vendor/composer/autoload_real.php
+++ b/tmp/phr_SBYnr7/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@
 
 
 
-class ComposerAutoloaderInitf6d95af9246e0e0e98e255e3bc14c82b
+class ComposerAutoloaderInitd4c7400998bd39c407a1d41a47cd86c6
 {
 private static $loader;
 
@@ -19,15 +19,15 @@ if (null !== self::$loader) {
 return self::$loader;
 }
 
-spl_autoload_register(array('ComposerAutoloaderInitf6d95af9246e0e0e98e255e3bc14c82b', 'loadClassLoader'), true, true);
+spl_autoload_register(array('ComposerAutoloaderInitd4c7400998bd39c407a1d41a47cd86c6', 'loadClassLoader'), true, true);
 self::$loader = $loader = new \Composer\Autoload\ClassLoader();
-spl_autoload_unregister(array('ComposerAutoloaderInitf6d95af9246e0e0e98e255e3bc14c82b', 'loadClassLoader'));
+spl_autoload_unregister(array('ComposerAutoloaderInitd4c7400998bd39c407a1d41a47cd86c6', 'loadClassLoader'));
 
 $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
 if ($useStaticLoader) {
 require_once __DIR__ . '/autoload_static.php';
 
-call_user_func(\Composer\Autoload\ComposerStaticInitf6d95af9246e0e0e98e255e3bc14c82b::getInitializer($loader));
+call_user_func(\Composer\Autoload\ComposerStaticInitd4c7400998bd39c407a1d41a47cd86c6::getInitializer($loader));
 } else {
 $map = require __DIR__ . '/autoload_namespaces.php';
 foreach ($map as $namespace => $path) {
@@ -48,19 +48,19 @@ $loader->addClassMap($classMap);
 $loader->register(true);
 
 if ($useStaticLoader) {
-$includeFiles = Composer\Autoload\ComposerStaticInitf6d95af9246e0e0e98e255e3bc14c82b::$files;
+$includeFiles = Composer\Autoload\ComposerStaticInitd4c7400998bd39c407a1d41a47cd86c6::$files;
 } else {
 $includeFiles = require __DIR__ . '/autoload_files.php';
 }
 foreach ($includeFiles as $fileIdentifier => $file) {
-composerRequiref6d95af9246e0e0e98e255e3bc14c82b($fileIdentifier, $file);
+composerRequired4c7400998bd39c407a1d41a47cd86c6($fileIdentifier, $file);
 }
 
 return $loader;
 }
 }
 
-function composerRequiref6d95af9246e0e0e98e255e3bc14c82b($fileIdentifier, $file)
+function composerRequired4c7400998bd39c407a1d41a47cd86c6($fileIdentifier, $file)
 {
 if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
 require $file;
diff --git a/tmp/phr_GPrhh5/vendor/composer/autoload_static.php b/tmp/phr_SBYnr7/vendor/composer/autoload_static.php
index d10ce9b..55ba104 100644
--- a/tmp/phr_GPrhh5/vendor/composer/autoload_static.php
+++ b/tmp/phr_SBYnr7/vendor/composer/autoload_static.php
@@ -4,7 +4,7 @@
 
 namespace Composer\Autoload;
 
-class ComposerStaticInitf6d95af9246e0e0e98e255e3bc14c82b
+class ComposerStaticInitd4c7400998bd39c407a1d41a47cd86c6
 {
 public static $files = array (
 '5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php',

GNU diffs (-d)

By default, Pharaoh will use git to generate a diff of the code. If you'd prefer a GNU diff, pass the -d flag, like so:

/path/to/pharaoh -d \
    /path/to/distributed.phar \
    /path/to/built-from-source-code.phar

Sample output:

$ pharaoh -d dist/sodium-compat-php5.phar dist/sodium-compat-php7.phar
Common subdirectories: /tmp/phr_EsTl2p/lib and /tmp/phr_UV3iJt/lib
Common subdirectories: /tmp/phr_EsTl2p/src and /tmp/phr_UV3iJt/src
Common subdirectories: /tmp/phr_EsTl2p/vendor and /tmp/phr_UV3iJt/vendor

File hashes (-c, --check)

If you're more interested in verifying the authenticity of a Pharaoh's contents from a quick scan, you can use the -c algo or --check=algo arguments to specify the hash function to use.

/path/to/pharaoh --check=sha256 \
    /path/to/distributed.phar \
    /path/to/built-from-source-code.phar

# This is equivalent to the above command:
/path/to/pharaoh -csha256 \
    /path/to/distributed.phar \
    /path/to/built-from-source-code.phar

Sample output:

$ pharaoh --check=blake2b dist/sodium-compat-php5.phar dist/sodium-compat-php7.phar
	/vendor/autoload.php
		83d3edc0cc50bbe1d4a05ec1c269359b1eddeb0d7d706f81c7bfb52e7a2dd86c	3310968acbf487a14e38e55077cf792bcd649f48e001717a35506f12031c97a9
	/vendor/composer/autoload_static.php
		a3e53155cbc5faccc2f8bb1d28dfe202ac033504d0e72268847bf33429bb47df	da215e6479739f87f04248880d0bfee78bd5d0828e61c8fb38a85902d42e844c
	/vendor/composer/autoload_real.php
		70e1113f73dc73a61594ee5cb724c44019f8f1a79321e51532a3cf0ef582b50c	1fd1127fb6a245128b5901f5d1087a1fbe0477e525d477192bd91a7623cf152a

All hash functions supported by PHP are accepted here. Additionally, if you specify blake2b, Pharaoh will use sodium_compat to generate a BLAKE2b hash of each file.


  Files folder image Files (11)  
File Role Description
Files folder imagedocs (1 file)
Files folder imagesrc (1 file, 1 directory)
Accessible without login Plain text file .travis.yml Data Auxiliary data
Accessible without login Plain text file composer.json Data Auxiliary data
Accessible without login Plain text file LICENSE Lic. License text
Accessible without login Plain text file pharaoh Data Auxiliary data
Accessible without login Plain text file psalm.xml Data Auxiliary data
Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files (11)  /  docs  
File Role Description
  Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files (11)  /  src  
File Role Description
Files folder imagePharaoh (3 files)
  Accessible without login Plain text file pharaoh.php Example Example script

  Files folder image Files (11)  /  src  /  Pharaoh  
File Role Description
  Accessible without login Plain text file Pharaoh.php Class Class source
  Accessible without login Plain text file PharDiff.php Class Class source
  Accessible without login Plain text file PharError.php Class Class source

The PHP Classes site has supported package installation using the Composer tool since 2013, as you may verify by reading this instructions page.
Install with Composer Install with Composer
 Version Control Unique User Downloads Download Rankings  
 100%
Total:43
This week:0
All time:10,838
This week:206Up