@@ -130,24 +130,54 @@ private function isRunningOS400(): bool
130130 */
131131 private function openOutputStream ()
132132 {
133+ static $ stdout ;
134+
135+ if ($ stdout ) {
136+ return $ stdout ;
137+ }
138+
133139 if (!$ this ->hasStdoutSupport ()) {
134- return fopen ('php://output ' , 'w ' );
140+ return $ stdout = fopen ('php://output ' , 'w ' );
135141 }
136142
137143 // Use STDOUT when possible to prevent from opening too many file descriptors
138- return \defined ('STDOUT ' ) ? \STDOUT : (@fopen ('php://stdout ' , 'w ' ) ?: fopen ('php://output ' , 'w ' ));
144+ if (!\defined ('STDOUT ' )) {
145+ return $ stdout = @fopen ('php://stdout ' , 'w ' ) ?: fopen ('php://output ' , 'w ' );
146+ }
147+
148+ // On Windows, STDOUT is opened in text mode; reopen in binary mode to prevent \n to \r\n conversion
149+ if ('\\' === \DIRECTORY_SEPARATOR ) {
150+ return $ stdout = @fopen ('php://stdout ' , 'w ' ) ?: \STDOUT ;
151+ }
152+
153+ return $ stdout = \STDOUT ;
139154 }
140155
141156 /**
142157 * @return resource
143158 */
144159 private function openErrorStream ()
145160 {
161+ static $ stderr ;
162+
163+ if ($ stderr ) {
164+ return $ stderr ;
165+ }
166+
146167 if (!$ this ->hasStderrSupport ()) {
147- return fopen ('php://output ' , 'w ' );
168+ return $ stderr = fopen ('php://output ' , 'w ' );
148169 }
149170
150171 // Use STDERR when possible to prevent from opening too many file descriptors
151- return \defined ('STDERR ' ) ? \STDERR : (@fopen ('php://stderr ' , 'w ' ) ?: fopen ('php://output ' , 'w ' ));
172+ if (!\defined ('STDERR ' )) {
173+ return $ stderr = @fopen ('php://stderr ' , 'w ' ) ?: fopen ('php://output ' , 'w ' );
174+ }
175+
176+ // On Windows, STDERR is opened in text mode; reopen in binary mode to prevent \n → \r\n conversion
177+ if ('\\' === \DIRECTORY_SEPARATOR ) {
178+ return $ stderr = @fopen ('php://stderr ' , 'w ' ) ?: \STDERR ;
179+ }
180+
181+ return $ stderr ??= \STDERR ;
152182 }
153183}
0 commit comments