외부 프로세스를 실행하고 표준 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)








Posted by bloodguy
,