Как правильно «вставить» программу CLI в PHP-скрипт *при выполнении вашей собственной функции*? (Мой старый метод сломался.)

#php #passthru

#php #пасстру

Вопрос:

Еще несколько дней назад у меня это работало. Это работало уже долгое время. Я не уверен, было ли это из-за обновления PHP с 8.0.12 до 8.0.13, или потому, что yt-dlp обновился и с тех пор что-то изменилось. Я не изменил свой код.

Это работает:

 passthru($yt_dlp_command);  

Однако это не позволяет мне запускать мою собственную функцию во время ее выполнения, в чем и весь смысл.

Это больше не работает, но работало до недавнего времени:

 ob_start(); $a = popen($yt_dlp_command, 'r');  if ($a) {  $response = fgets($a, 10); // I've tried numerous other values than 10 as well.   if ($response)  {  while ($row_data = $response)  {  ob_flush();  flush();  my_function();  echo $row_data;  }  }   pclose($a); }  ob_end_clean();  

Независимо от того, какие варианты я использую для yt-dlp, такие как --no-progress или --newline (или их комбинации, или их нет), он просто не покажет ничего, кроме первой строки или начала первой строки, бесконечно повторяющейся прерывистым образом.

Если я запускаю $yt_dlp_command в a cmd.exe , он отлично работает с полным анимированным выводом и все такое.

Теперь я полностью застрял. Понятия не имею, что еще можно попробовать. Вероятно, это yt-dlp что-то изменил в том, как он выводит данные, но даже если это так, мне странно, как некоторые программы могут просто взломать этот код. Он должен работать независимо от того, какая конкретная программа запускается.

Комментарии:

1. Вероятно, мы не сможем дать вам полезный ответ, не зная всего или некоторых из следующих вопросов: 1) Что такое ваша команда $yt_dlp_command (или, по крайней мере, пример того, что вы пробовали) 2) Что должна делать функция my_function ()? 3) Каково ожидаемое поведение/вывод этого скрипта? 4) Какую версию yt-dlp вы используете?

2. 1. Не имеет значения. 2. Это просто пример функции, которая вызывается во время вывода. 3. Пожалуйста, прочтите. 4. Последние, всегда.

3. Я пытаюсь помочь вам здесь, но информация, которую я прошу, не является необычной и, скорее всего, содержит ключевую информацию, необходимую для того, чтобы помочь вам разобраться в вашей проблеме. Опять же: 1) Как вы ожидаете, что мы вам поможем, если мы даже не можем воспроизвести ввод, которым задыхается ваш скрипт? 2) Содержимое этой функции вполне может изменять состояние или приводить к зависанию скрипта. Если функция my_function() не имеет существенного значения для поведения, я предлагаю прокомментировать ее или удалить из вашего примера. 3) Я спрашиваю, что вы хотите , чтобы он делал. 4) Лучше всего явно перечислить для потомков.

4. @jpheldson Весь смысл кода заключается в одновременном запуске функции. Вот почему раздается звонок. Ты не читаешь, как и все в наши дни. Из-за этого получить помощь стало практически невозможно.

5. в своем вопросе вы говорите: «Теперь я полностью застрял». Застревание часто является результатом сосредоточения внимания на неправильной части проблемы. Распространенный способ избавиться от этого — «сделать шаг назад», обосновав все предположения, связанные с решением. Решение вашей проблемы, скорее всего, скрыто в тех деталях, которые вы считаете неуместными. Например, распространенная проблема, которая может нарушить подобный сценарий, заключается в том, что операционные системы часто буферизуют каналы между процессами. Это было бы трудно проверить, не имея примера выполняемой вами команды yt-dlp.

Ответ №1:

Немного поиграв с вашим сценарием, я понял, что условие вашего цикла while никогда не обновляется, поэтому он бесконечно повторяется с первым возвращенным битом данных. По крайней мере, я бы рекомендовал добавить еще один вызов fgets() в нижней части цикла while, чтобы получить следующий бит данных из разветвленного вызова процесса.

Комментарии:

1. Но тогда как же это прекрасно работало до недавнего времени?

2. Это, мой друг, предположение, от которого мне пришлось отступить. Всегда полезно перепроверять предположения. Возможно, в какой-то момент ваш сценарий был непреднамеренно отредактирован.