Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions src/Commands/BuildBinCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@
#[AsCommand('build:bin', 'build bin')]
class BuildBinCommand extends BuildPharCommand
{
protected string $binFileName;

public function __construct()
{
parent::__construct();
$this->binFileName = config('plugin.webman.console.app.bin_filename', 'webman.bin');
}

/**
* @return void
*/
Expand All @@ -37,16 +45,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$version = max($version, 8.1);
$supportZip = class_exists(ZipArchive::class);
$microZipFileName = $supportZip ? "php$version.micro.sfx.zip" : "php$version.micro.sfx";
$pharFileName = config('plugin.webman.console.app.phar_filename', 'webman.phar');
$binFileName = config('plugin.webman.console.app.bin_filename', 'webman.bin');
$this->buildDir = config('plugin.webman.console.app.build_dir', base_path() . '/build');
$customIni = config('plugin.webman.console.app.custom_ini', '');

$binFile = "$this->buildDir/$binFileName";
$pharFile = "$this->buildDir/$pharFileName";
$zipFile = "$this->buildDir/$microZipFileName";
$sfxFile = "$this->buildDir/php$version.micro.sfx";
$customIniHeaderFile = "$this->buildDir/custominiheader.bin";
$binFile = $this->buildDir. DIRECTORY_SEPARATOR . $this->binFileName;
$pharFile = $this->buildDir . DIRECTORY_SEPARATOR . $this->getPharFileName();
$zipFile = $this->buildDir. DIRECTORY_SEPARATOR . $microZipFileName;
$sfxFile = $this->buildDir. DIRECTORY_SEPARATOR . "php$version.micro.sfx";
$customIniHeaderFile = $this->buildDir. DIRECTORY_SEPARATOR . "custominiheader.bin";

// 打包
$command = new BuildPharCommand();
Expand Down Expand Up @@ -137,7 +142,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
// 添加执行权限
chmod($binFile, 0755);

$output->writeln("\r\nSaved $binFileName to $binFile\r\nBuild Success!\r\n");
$output->writeln("\r\nSaved $this->binFileName to $binFile\r\nBuild Success!\r\n");

return self::SUCCESS;
}
Expand Down
83 changes: 69 additions & 14 deletions src/Commands/BuildPharCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,21 @@
#[AsCommand('build:phar', 'Can be easily packaged a project into phar files. Easy to distribute and use.')]
class BuildPharCommand extends Command
{
protected $buildDir = '';
protected string $pharFileName;

public function __construct(?string $name = null)
protected string $buildDir;

protected int $pharFormat;

protected int $pharCompression;

public function __construct()
{
parent::__construct($name);
$this->buildDir = config('plugin.webman.console.app.build_dir', base_path() . '/build');
parent::__construct();
$this->pharFileName = config('plugin.webman.console.app.phar_filename', 'webman.phar');
$this->buildDir = rtrim(config('plugin.webman.console.app.build_dir', base_path() . '/build'), DIRECTORY_SEPARATOR);
$this->pharFormat = config('plugin.webman.console.app.phar_format', Phar::PHAR);
$this->pharCompression = config('plugin.webman.console.app.phar_compression', Phar::NONE);
}

/**
Expand All @@ -34,19 +43,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}
}

$phar_filename = config('plugin.webman.console.app.phar_filename', 'webman.phar');
if (empty($phar_filename)) {
throw new RuntimeException('Please set the phar filename.');
}

$phar_file = rtrim($this->buildDir,DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $phar_filename;
$phar_file = $this->buildDir . DIRECTORY_SEPARATOR . $this->getPharFileName();
if (file_exists($phar_file)) {
unlink($phar_file);
}

$exclude_pattern = config('plugin.webman.console.app.exclude_pattern','');

$phar = new Phar($phar_file,0,'webman');
$phar = new Phar($this->buildDir . DIRECTORY_SEPARATOR . $this->pharFileName,0 , 'webman');
if(!str_ends_with($this->getPharFileName(), '.phar')) {
$phar = $phar->convertToExecutable($this->pharFormat, $this->pharCompression);
}

$phar->startBuffering();

Expand All @@ -62,9 +69,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$private = openssl_get_privatekey(file_get_contents($private_key_file));
$pkey = '';
openssl_pkey_export($private, $pkey);
$phar->setSignatureAlgorithm($signature_algorithm, $pkey);
!$phar->getSignature() && $phar->setSignatureAlgorithm($signature_algorithm, $pkey);
} else {
$phar->setSignatureAlgorithm($signature_algorithm);
!$phar->getSignature() && $phar->setSignatureAlgorithm($signature_algorithm);
}

$phar->buildFromDirectory(BASE_PATH,$exclude_pattern);
Expand Down Expand Up @@ -98,6 +105,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}
}

if ($this->pharCompression != Phar::NONE) {
$phar->addFromString('vendor/composer/ClassLoader.php', $this->getClassLoaderContents());
$phar->addFromString('/vendor/workerman/workerman/src/Worker.php', $this->getWorkerContents());
}
$output->writeln('Files collect complete, begin add file to Phar.');

$phar->setStub("#!/usr/bin/env php
Expand All @@ -111,6 +122,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$output->writeln('Write requests to the Phar archive, save changes to disk.');

$phar->stopBuffering();

unset($phar);
return self::SUCCESS;
}
Expand All @@ -131,5 +143,48 @@ public function checkEnv(): void
);
}
}


public function getPharFileName(): string
{
$phar_filename = $this->pharFileName;
if (empty($phar_filename)) {
throw new RuntimeException('Please set the phar filename.');
}
$phar_filename .= match ($this->pharFormat) {
Phar::TAR => '.tar',
Phar::ZIP => 'zip',
default => ''
};
$phar_filename .= match ($this->pharCompression) {
Phar::GZ => '.gz',
Phar::BZ2 => '.bz2',
default => ''
};
return $phar_filename;
}

public function getClassLoaderContents(): string
{
$fileContents = file_get_contents(BASE_PATH . '/vendor/composer/ClassLoader.php');
$replaceContents = <<<'PHP'
if (str_starts_with($file, 'phar://')) {
$lockFile = sys_get_temp_dir() . '/phar_' . md5($file) . '.lock';
$fp = fopen($lockFile, 'c');
flock($fp, LOCK_EX) && include $file;
fclose($fp);
file_exists($lockFile) && @unlink($lockFile);
} else {
include $file;
}
PHP;
return str_replace(' include $file;', $replaceContents, $fileContents);
}
public function getWorkerContents(): string
{
$fileContents = file_get_contents(BASE_PATH . '/vendor/workerman/workerman/src/Worker.php');
$replaceContents = <<<'PHP'
static::forkOneWorkerForLinux($worker); php_sapi_name() == 'micro' && usleep(50000);
PHP;
return str_replace('static::forkOneWorkerForLinux($worker);', $replaceContents, $fileContents);
}
}
4 changes: 4 additions & 0 deletions src/config/plugin/webman/console/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

'phar_filename' => 'webman.phar',

'phar_format' => Phar::PHAR, // Phar archive format: Phar::PHAR, Phar::TAR, Phar::ZIP

'phar_compression' => Phar::NONE, // Compression method for Phar archive: Phar::NONE, Phar::GZ, Phar::BZ2

'bin_filename' => 'webman.bin',

'signature_algorithm'=> Phar::SHA256, //set the signature algorithm for a phar and apply it. The signature algorithm must be one of Phar::MD5, Phar::SHA1, Phar::SHA256, Phar::SHA512, or Phar::OPENSSL.
Expand Down