powered by simpleCommunicator - 2.0.28     © 2024 Programmizd 02
Map
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / PHP: Перенаправить вывод для одной функции
10 сообщений из 10, страница 1 из 1
PHP: Перенаправить вывод для одной функции
    #40064732
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть PHP-скрипт, который может запускаться как интерактивно (с выводом в терминал), так и планировщиком (с выводом в log-файл).
В скрипте последовательно вызывается несколько функций.
Можно ли сделать так, перед вызовом stdout менялся на конкретный файл, а после возврата функции stdout восстанавливался?

Я пробовал делать fopen перед вызовом функции, в результате вывод перенаправлялся в файл.
Но при этом после возврата функции не получалось восстановить stdout, несмотря на то, что я сохранял posix_ttyname и после возврата пробовал сделать fopen на сохраненное значение.
...
Рейтинг: 0 / 0
PHP: Перенаправить вывод для одной функции
    #40064815
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.
не получалось восстановить stdout, несмотря на то, что я сохранял posix_ttyname и после возврата пробовал сделать fopen на сохраненное значение.
А если стандарно, 'php://output' задать?
https://www.php.net/manual/ru/wrappers.php.php
...
Рейтинг: 0 / 0
PHP: Перенаправить вывод для одной функции
    #40064906
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На примере не покажите?

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
if (...) {
  proc('p1');
  proc('p2');
  ...
}

function proc($proc)
{
  //перенаправить stdout в $proc.log
  $proc();
  //вернуть stdout
}

function p1()
{
  ...
}
...
...
Рейтинг: 0 / 0
PHP: Перенаправить вывод для одной функции
    #40064913
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сделал так:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
function proc($source)
{
	global $script;
	$proc = "proc_{$source}";
	$log = "{$script}_{$source}.log";
	if (!function_exists($proc)) return;
	print PHP_EOL;
	$fh = fopen($log,'w');
	$rc = ob_start(function($buffer) use($fh) { fwrite($fh, $buffer); return ''; });
	$proc();
	ob_end_clean();
	fclose($fh);
}


В принципе работает именно так, как мне нужно.
Но мне не нравится буферизация и ее особенности/ограничения.
Я бы предпочел перенаправление вывода.
...
Рейтинг: 0 / 0
PHP: Перенаправить вывод для одной функции
    #40064970
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.
На примере не покажите?
Так покажите свой реально нерабочий тестовый пример, где fopen делаете и потом вернуть пытаетесь, но не получается. Или за Вас я должен придумать пример, показывающий, что Вам надо?
Давайте на Вашем примере посмотрим, что можно намутить.
Лишний код, не имеющий явного и прямого отношения к проблеме, в пример не включайте, но каменты, конечно же, приветствуются.
...
Рейтинг: 0 / 0
PHP: Перенаправить вывод для одной функции
    #40064976
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот исходная программа:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
print "*** START \n";

proc('p1');
proc('p2');

print "*** END \n";

function proc($proc)
{
        print "** PROC\n";
        $proc();
}

function p1()
{
        print "* P1\n";
}

function p2()
{
        print "* P2\n";
}



А вот пример:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
print "*** START \n";

proc('p1');
proc('p2');

print "*** END \n";

function proc($proc)
{
        global $STDOUT;
        print "** PROC\n";
        $old = posix_ttyname(STDOUT);
        print "#{$proc} old tty: {$old}\n";
        fclose(STDOUT);
        $STDOUT = fopen("{$proc}.log", 'wb');
        print "#{$proc} new tty: $STDOUT\n";
        $proc();
        fclose($STDOUT);
        $STDOUT = fopen($old, 'wb');
        print "#{$proc} def tty: $STDOUT\n";
}

function p1()
{
        print "* P1\n";
}

function p2()
{
        print "* P2\n";
}



При запуске должен написать в консоль START, PROC и END, а P1 и P2 должны быть выведены в файлы p1.log и p2.log соответственно.
Но в данном примере в консоль выводится START и PROC, в файл p1.log выводится P1, а остальное пропадает.
...
Рейтинг: 0 / 0
PHP: Перенаправить вывод для одной функции
    #40064987
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Занятно. Ошибки в консоль не вываливаются?
Мне напечатало:
Код: php
1.
PHP Warning:  posix_ttyname(): supplied resource is not a valid stream resource in /home/vk/t.php on line 14

Это строка
Код: php
1.
        $old = posix_ttyname(STDOUT);



Ладно, глядим значение константы
Код: php
1.
2.
$ php -r 'echo STDOUT;'
Resource id #2


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

Что видим.
Код: php
1.
2.
3.
4.
5.
6.
$ php -r 'var_dump(STDOUT); /*fclose(STDOUT);*/ var_dump(STDOUT);'
Command line code:1:
resource(2) of type (stream)
Command line code:1:
resource(2) of type (stream)
$ 


А так... Гхм...
Код: php
1.
2.
3.
4.
$ php -r 'var_dump(STDOUT); fclose(STDOUT); var_dump(STDOUT);'
Command line code:1:
resource(2) of type (stream)
$ 



Видимо, потому, как Вы и пишите:
Alibek B.
не получалось восстановить stdout
Ресурс закрыт, а переопределить константу с вновь открытым ресурсом... ну, понимаете.


Вероятно, остается делать какой-то приблизительно такого плана веселый замут, избавившись от дефолтового stdout и определить поток вывода явно (впрочем, это можно заметно упростить):
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
<?php

$fdOUT = fopen('php://stdout', 'wb');
fwrite($fdOUT,  "*** START \n");

proc('p1');
proc('p2');

fwrite($fdOUT,  "*** END \n");


function proc($proc)
{
        global $fdOUT;
        fwrite($fdOUT, "** PROC\n");
        fwrite($fdOUT, "#{$proc} old tty: {$fdOUT}\n");
        fclose($fdOUT);
        $fdOUT = fopen("{$proc}.log", 'wb');
        fwrite($fdOUT, "#{$proc} new tty: $fdOUT\n");
        $proc();
        fclose($fdOUT);
        $fdOUT = fopen('php://stdout', 'wb');
        fwrite($fdOUT, "#{$proc} def tty: $fdOUT\n");
}

function p1()
{
        global $fdOUT;
        fwrite($fdOUT, "* P1\n");
}

function p2()
{
        global $fdOUT;
        fwrite($fdOUT, "* P2\n");
}


Или, вообще, пересмотреть концепцию вывода. Например, в скрипте выводить всё в один поток, а в среде вызова разделять, направляя часть вывода по маркерам в файл. Ну это на уровне идеи. Не пробовал, может быть можно (а может и нет) определить в пхп четвертый, пятый и т.д. потоки и ими играть в среде вызова (в командной строке).
...
Рейтинг: 0 / 0
PHP: Перенаправить вывод для одной функции
    #40065077
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkle
Вероятно, остается делать какой-то приблизительно такого плана веселый замут, избавившись от дефолтового stdout и определить поток вывода явно (впрочем, это можно заметно упростить)

Выглядит криво и неудобно. Уж лучше буферизацию использовать.

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

Это уже усложнение ради усложнения.
Я как раз хотел упростить и сделать скелет скрипта прозрачным.
Как в bash-скриптах, в которых можно вызвать подпрограмму и перенаправить ее вывод по конвейеру.
...
Рейтинг: 0 / 0
PHP: Перенаправить вывод для одной функции
    #40065219
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.
Выглядит криво и неудобно.
Совершенно согласен. Плюс не быстро всякий раз открывать и закрывать файловый дескриптор. Однако, это исключительно из разряда "как-то приблизительно так" и столь же далеко до реальной реализации как от Луны до Нептуна.
...
Рейтинг: 0 / 0
PHP: Перенаправить вывод для одной функции
    #40135953
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не появилось ли в PHP 7 более удобного способа?
Вроде бы эта библиотека позволяет более гибко работать с потоками.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / PHP: Перенаправить вывод для одной функции
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]