phar無法對(duì)可執(zhí)行文件打包,打包后php調(diào)用exec()函數(shù)訪問不到該可執(zhí)行文件。
第三方提供了一個(gè)編譯后的C++可執(zhí)行文件AServer
,我需要使用php執(zhí)行這個(gè)文件,未打包前是可以正常執(zhí)行的,但是打包后,exec()函數(shù)就不能訪問這個(gè)可執(zhí)行文件了,webman控制臺(tái)提示
sh: 1: phar:///code/webman-project-v1.0.phar/app/bin/AServer: not found
剛開始懷疑AServer
未被打包進(jìn)app/bin/
目錄下,但是查看webman-project-v1.0.phar
包內(nèi)容,發(fā)現(xiàn)是有這個(gè)文件的,是由于phar打包底層的問題,還是沒有執(zhí)行權(quán)限?,應(yīng)該怎么解決呢?
$command = app_path() . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'AServer';
exec($command, $output);
打包配置config/plugin/webman/console/app.php
return [
'enable' => true,
'phar_file_output_dir' => BASE_PATH . DIRECTORY_SEPARATOR . 'build',
'phar_filename' => 'webman-project-' . env('VERSION', '0.0') . '.phar',
'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.
'private_key_file' => '', // The file path for certificate or OpenSSL private key file.
'exclude_pattern' => '#^(?!.*(config/plugin/webman/console/app.php|webman/console/src/Commands/(PharPackCommand.php|ReloadCommand.php)|LICENSE|composer.json|.github|.idea|doc|docs|.git|.setting|runtime|test|test_old|tests|Tests|vendor-bin|.md))(.*)$#',
'exclude_files' => [
'.env.example', 'LICENSE', 'composer.json', 'composer.lock', 'start.php'
]
];
感謝@fuzqing老哥提出的解決方案,現(xiàn)在整理成以下:
xxx.phar
文件相對(duì)目錄中Phar::running()
方法可以判斷出當(dāng)前環(huán)境是是否在phar
中phar
與非phar
中的邏輯support/helpers.php
中增加bin_path()函數(shù),用來區(qū)分phar環(huán)境與非phar環(huán)境
/**
* 獲得腳本運(yùn)行路徑
* 如果是在phar中,則將phar同級(jí)路徑下runtime/bin/目錄作為腳本執(zhí)行路徑
* 若果在非phar中,則將app/bin/目錄作為腳本執(zhí)行路徑
* @return false|string
*/
function bin_path()
{
return is_phar() ? runtime_path() . DIRECTORY_SEPARATOR . 'bin' : realpath(app_path() . DIRECTORY_SEPARATOR .'bin');
}
增加方法,在需要的地方執(zhí)行,若phar環(huán)境下,需要拷貝執(zhí)行文件到runtime/bin/目錄下
/**
* 生成phar環(huán)境下所需二進(jìn)制文件
*/
protected function genderBinaryForPhar(): void
{
// phar環(huán)境下
if (is_phar()) {
// 原路徑
$sourceBinaryPath = app_path() . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'AServer';
// 目標(biāo)路徑
$targetBinaryPath = bin_path() . DIRECTORY_SEPARATOR . 'AServer';
// 生成所需二進(jìn)制文件
if (!file_exists($targetBinaryPath) && file_exists($sourceBinaryPath)) {
$targetDirectory = dirname($targetBinaryPath);
if (!is_dir($targetDirectory)) {
mkdir($targetDirectory);
}
copy($sourceBinaryPath, $targetBinaryPath);
chmod($this->genderCommand, 644);
}
}
}