Windows-эквивалент специального инструмента сжатия LINUX

В LINUX есть очень специфическая утилита/инструмент сжатия по адресу /usr/bin/xz.

Теперь я использую Windows 10 x64 с PHP 8.1, и у меня есть библиотека php, которая в одной строке своего кода вызывает этот очень специфический файл LINUX (все остальное в этом коде совместимо с Windows, за исключением этой строки кода) с некоторые конкретные переключатели, задающие его параметры. Это строка:

$x = proc_open("/usr/bin/xz '--format=raw' '--lzma1=lc=3,lp=0,pb=2,dict=128KiB' '-c' '-'", [0 => ["pipe", "r"], 1 => ["pipe", "w"]], $p);

Я пытаюсь найти какую-нибудь утилиту, эквивалентную Windows, которую я мог бы заменить этой утилитой LINUX, которая принимала бы некоторые аналогичные переключатели для установки своих атрибутов, формулировки могут быть другими - это не было бы проблемой, я бы просто изменил их соответствующим образом.

Я думал, что Windows XZ Utils может быть именно таким, но, к сожалению, их xz.exe не принимает никаких переключателей, которые бы устанавливали его атрибуты, как это делает файл LINUX.

Есть ли какое-нибудь приложение для Windows (или, может быть, даже PHP-скрипт?), которое могло бы выполнять сжатие данных lzma1, аналогичное LINUX /usr/bin/xz, которое я мог бы использовать под Windows?

Я только что скачал двоичный файл Windows. Хотя на странице --help этого не показано, насколько я могу судить, все переключатели, которые вы указали, сработали. При тестировании пропустите PHP. Начните с того, чтобы заставить это работать в Windows CLI в целом. Как только это заработает, переключитесь на PHP.

Chris Haas 12.06.2024 19:57

О, это интересная находка, спасибо. Но почему это просто не работает в PHP? Или я говорю это по-другому: не могли бы вы опубликовать точную строку, которую вы сейчас использовали с двоичным файлом Windows, пожалуйста? + файлы из какой именно папки вы использовали (в zip-файле несколько папок с разными версиями)? Я использовал те, что для x64.

theoneiam 12.06.2024 20:00

@ChrisHaas, не могли бы вы также загрузить исходный пример сценария отсюда jan.fecik.sk/files/… подставьте туда эту строку для вашей версии Windows и скажите мне, каково значение переменной $o (строка 26)? Потому что мой по-прежнему ПУСТОЙ, но, я думаю, там должна быть довольно длинная строка букв и цифр.

theoneiam 12.06.2024 20:12

@ChrisHaas относительно вашего принятого ответа - теперь у меня есть проблема: я пытаюсь создать ОТНОСИТЕЛЬНЫЙ ПУТЬ к xz.exe вместо АБСОЛЮТНОГО ПУТИ, который может создать проблемы после развертывания на работающем сервере. По какой-то причине это не работает: если я проверю существование xz.exe с помощью if (file_exists("xz.exe")), все пройдет нормально, но как только я заменю ваш абсолютный путь на $xz = "xz.exe"; или $xz = "xz"; это не работает. Можете ли вы посоветовать мне, как это решить, пожалуйста?

theoneiam 13.06.2024 12:07

Во-первых, обычно лучше прикреплять комментарии к самому ответу, а не к исходному вопросу, так как другим будет сложно его прочитать. К вашему комментарию, гораздо проще отлаживать абсолютный путь вместо относительного пути, и тем более, чем «нет пути», которым является просто «xy.exe». Ваше мнение о том, что такое относительный/отсутствующий путь, часто не совпадает с тем, что думает PHP. Вот почему мы используем такие вещи, как __DIR__ и dirname(), чтобы построить абсолютный путь относительно. Значит xz.exe будет жить в той же папке, что и скрипт, тогда мой код будет портативным. Будет ли он жить относительно, попробуйте добавить dirname

Chris Haas 13.06.2024 15:26

Простое объяснение: изначально у меня был этот вопрос под вашим постом, НО я подумал, что что-то не так, потому что ответа не было несколько часов, затем я удалил его и разместил здесь, и вуаля, вы ответили. :-) Вот и все, еще раз извините. Меня беспокоит то, что когда __DIR__ вызывается из сценария на реальном сервере, если это не нарушает какие-то ограничения пути к серверу - извините, я не профессионал, поэтому мои вопросы могут показаться профессионалам глупыми (я пытаюсь понять все об этом еще).

theoneiam 13.06.2024 15:58

Константа __DIR__ — это «Каталог файла. Если она используется внутри включения, возвращается каталог включаемого файла». Это гарантированно работает везде. Если у учетной записи пользователя нет разрешения на доступ к чему-либо, абсолютное и относительное ничего не исправит.

Chris Haas 13.06.2024 16:02

Я спрашивал, нельзя ли использовать просто ./xz.exe без полного пути? Требуется ли для этого .exe указание полного пути?

theoneiam 13.06.2024 16:05

Мой лучший ответ — «может быть». Когда вы используете ./xz.exe, это не относительно текущего каталога (cd), а относительно текущего рабочего каталога (cwd). Часто/иногда cd и cwd совпадают, но это не гарантия. Однако показанная мной версия всегда создает абсолютный путь относительно компакт-диска. Лично я бы просто рекомендовал попробовать использовать __DIR__ на вашем реальном сервере, чтобы развеять любые опасения. Именно так работает практически каждая система, которую я построил и с которой столкнулся.

Chris Haas 13.06.2024 16:41

Хорошо, Крис, я попробую это сделать, как только веб-страница будет полностью готова на работающем сервере, надеюсь, что все будет хорошо, поскольку у меня нет опыта в подобных вещах. И только одно замечание, которое приходит мне на ум прямо сейчас: может ли быть на рабочем сервере какая-то проблема с вызовом .exe-файла из сценария (все будет размещено рядом точно так же, как в вашем примере - теперь это работает на моем тестовый сервер, это .exe рядом с .php)?

theoneiam 13.06.2024 17:22

Да, вполне возможно, что учетная запись пользователя, под которой работает PHP, не будет иметь разрешения на запуск исполняемого файла. Эту проблему необходимо будет решить с помощью системы разрешений ОС. Но сначала попробуйте, прежде чем погружаться в это слишком глубоко. В PHP также есть функция, с помощью которой вы можете отключить основные функции в php.ini, а по соображениям безопасности/производительности [некоторые хосты отключают proc_open и другие исполняемые функции. Если вы получаете «вызов неопределенной функции», возможно, это причина. Но еще раз, просто попробуйте.

Chris Haas 13.06.2024 17:31
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
11
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот моя версия вашего кода, надеюсь, комментарии добавят ясности.

Во-первых, я не скачивал запрошенный вами файл, я использовал файл отсюда: https://tukaani.org/xz/old.html#_windows

Во-вторых, моя версия предполагает, что PHP-скрипт и файл xz.exe находятся в одной папке. Если у вас это не так, сначала попробуйте мою версию, а затем попытайтесь выяснить, как изменить путь.

В-третьих, моя версия тестировалась только в CLI, у меня нет возможности запускать PHP на моем компьютере с Windows (кроме как через WSL).

В-четвертых, этот код записывает некоторый образец текста в стандартный ввод и сжимает его, и в случае успеха он выводит двоичный текст (который бесполезен, но показывает, что он работает). Обычно вы сохраняете это на диск, в кодировке Base64 или что-то еще.

<?php

// Variable for the current directory
$dir = __DIR__;

// Absolute path to the binary. This code assumes that it is in the
// same folder as this PHP script.
$xz = $dir . DIRECTORY_SEPARATOR . 'xz';

// Pipes to read/write to
$descriptorspec = [
   0 => ["pipe", "r"],
   1 => ["pipe", "w"],
   2 => ["pipe", "w"],
];

// Open the process. Use the array format so that automatic
// escaping is handled for you.
$process = proc_open(
    [
        $xz,
        '--format=raw',
        '--lzma1=lc=3,lp=0,pb=2,dict=128KiB',
        '-c',
        '-',
    ],
    $descriptorspec,
    $pipes
);

// Make sure the above worked
if (!$process){
    throw new RuntimeException('Could not open proc');
}

// Write some text to the stream to compress. You could also use
// file_get_contents or one of the command line switches
fwrite($pipes[0], 'This is a test');

// We're done writing
fclose($pipes[0]);

// Grab the contents of stdout and stderr
$output = stream_get_contents($pipes[1]);
$error  = stream_get_contents($pipes[2]);

fclose($pipes[1]);
fclose($pipes[2]);

// Clean up
if (!$return_value = proc_close($process)){
    // Successfully ran the command, do something with $output
    echo 'Output:', PHP_EOL, $output;
}else{
    echo 'There was an error, the command returned: ' . $return_value;
    echo PHP_EOL;
    echo $error;
}

Другие вопросы по теме