외부 프로세스를 실행하고 표준 I/O 스트림에 빨대를 꽂기 위해 proc_open 함수를 사용하는데,
빨대는 2번째 매개변수인 $descriptorspec에 지정함.
$descriptorspec = array(
// STDIN
0 => array('pipe', 'r'),
// STDOUT
1 => array('pipe', 'w'),
// STDERR
2 => array('pipe', 'w')
);
근데 이게 Windows에서 사용할 때, 만약 STDERR가 있을 경우 무한 blocking 상태에 빠지게 됨.
일단 무한 blocking 자체는 rw 모드를 'a' 로 처리해주면 방지할 수는 있으나,
실제 에러 메세지는 가져오질 못함.
이 모든걸 해결하는 방법은 스트림을 pipe로 하지 말고 file 로 하는 것.
// STDERR용 임시파일
$err_file = tempnam(sys_get_temp_dir(), 'err');
$descriptorspec = array(
// STDIN
0 => array('pipe', 'r'),
// STDOUT
1 => array('pipe', 'w'),
// STDERR
2 => array('file', $err_file, 'w')
);
임시파일을 하나 생성하고 stderr는 해당 파일로 리다이렉트한 후 proc_open()을 실행시키고,
프로세스가 끝나면 해당 임시파일을 읽어오고 지워주는 방식.
아래 링크에 보면 종합적인 예제가 있음.
[PHP] 프로세스를 실행시키면서 STDOUT, STDERR를 문자열 변수에 담기 (open_proc, descriptor_spec, stream_get_contents)