Skip to content

Instantly share code, notes, and snippets.

@milo
Created January 4, 2014 16:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save milo/8257075 to your computer and use it in GitHub Desktop.
Save milo/8257075 to your computer and use it in GitHub Desktop.
Small PHAR extract script
#!/usr/bin/env php
<?php
error_reporting(E_ALL | E_STRICT);
$opts = getOptions();
# Help
if (array_key_exists('h', $opts)) {
echo "PHAR content extract by Milo (https://github.com/milo)\n";
echo "\n";
echo "Usage: " . basename(__FILE__) . " -s source\n";
echo " -s source path to source PHAR file\n";
echo "\n";
echo " Options:\n";
echo " -l list content only\n";
echo " -L list content only, full filesystem path\n";
echo "\n";
echo " -b [file] extract boot loader (stub) too (default: PHAR name)\n";
echo " -B show boot loader and exit\n";
echo "\n";
echo " -d directory extract here (default: PHAR name)\n";
echo "\n";
echo " -h show this help and exit\n";
echo "\n";
exit(2);
}
# Source file check
if (!isset($opts['s'])) {
echo "Missing -s source PHAR file. Use -h for help.\n";
exit(2);
}
$srcFile = $opts['s'];
if (!is_file($srcFile)) {
echo "Source file '$srcFile' is not a file. Use -h for help.\n";
exit(1);
}
# PHAR open
try {
$phar = new Phar($srcFile);
} catch (Exception $e) {
echo "Cannot open PHAR file '$srcFile'. Is really in a PHAR format?\n";
echo "Original (maybe confusing) error message:\n\t{$e->getMessage()}\n";
exit(1);
}
# List only
if (($long = array_key_exists('L', $opts)) || array_key_exists('l', $opts)) {
$trim = strlen('phar://' . realpath($srcFile) . DIRECTORY_SEPARATOR);
foreach (new RecursiveIteratorIterator($phar) as $path => $foo) {
echo ($long ? $path : substr($path, $trim)) . "\n";
}
exit(0);
}
# Boot loader
if (($show = array_key_exists('B', $opts)) || array_key_exists('b', $opts)) {
$stub = $phar->getStub();
if ($show) {
echo $stub;
exit(0);
}
$dstStub = pathinfo($srcFile, PATHINFO_FILENAME) . '.stub.php';
if (is_string($opts['b'])) {
$dstStub = $opts['b'];
}
}
# Extract
$dstDir = isset($opts['d'])
? $opts['d']
: pathinfo($srcFile, PATHINFO_FILENAME);
if (file_exists($dstDir)) {
echo "Destination '$dstDir' already exists. Use -h for help with other options.\n";
exit(1);
}
if (isset($dstStub)) {
if (file_exists($dstStub)) {
echo "Destination for boot loader (stub) '$dstStub' already exists. Use -h for help.\n";
exit(1);
}
if (file_put_contents($dstStub, $stub) === FALSE) {
echo "Cannot save boot loader (stub) '$dstStub'.\n";
exit(1);
}
echo "Boot loader (stub) saved to '$dstStub'.\n";
}
if (!mkdir($dstDir, 0700, TRUE)) {
echo "Cannot create destination directory '$dstDir'.";
exit(1);
}
$phar->extractTo($dstDir);
echo "Extract to '$dstDir' done.\n";
exit(0);
/** @return array */
function getOptions() {
$args = isset($_SERVER['argv']) ? $_SERVER['argv'] : array();
$argc = count($args);
$opts = array();
$isOpt = function($s, & $o) {
if (preg_match('#^-([a-z])$#i', $s, $m)) {
$o = $m[1];
return TRUE;
}
return FALSE;
};
for ($i = 1; $i < $argc; $i++) {
$curr = $args[$i];
$next = & $args[$i+1];
if ($isOpt($curr, $opt)) {
if ($isOpt($next, $foo)) {
$opts[$opt] = NULL;
} else {
$opts[$opt] = $next;
$i++;
}
} else {
$opts[] = $curr;
}
}
return $opts;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment