fix: don't treat a finished request's write as an aborted connection (#2569)
## Summary
`go_ub_write()` reported any PHP output write that happens after
`fastcgi_finish_request()`/`frankenphp_finish_request()` as an aborted
connection (`0` bytes written, `closed=true`), regardless of whether the
client was actually still connected. `frankenphp_ub_write()` then calls
`php_handle_aborted_connection()` for that write, which:
- marks `connection_status()` as aborted even though the request
finished normally, and
- when `ignore_user_abort` is off (PHP's default outside worker mode),
calls `zend_bailout()`, silently terminating the rest of the script
right at that output statement.
Worker mode forces `ignore_user_abort=1` on every request, which is why
this doesn't visibly crash a worker script — it only corrupts
`connection_status()` there. Outside worker mode, any code that
echoes/outputs anything after `fastcgi_finish_request()` gets silently
truncated.
## Fix
Discard the write (the responseWriter may no longer be safe to touch,
see #2535/#2538), but report the *actual* client-disconnect status via
`fc.clientHasClosed()` instead of hardcoding `true`.
## Reproducer
```php
<?php
echo "Before";
fastcgi_finish_request();
echo "After";
```
In classic (non-worker) mode with default `ignore_user_abort`, `echo
"After"` triggers the bailout and any code after it never runs.
## Tests
- Extended `TestFinishRequest` (`testdata/finish-request.php`) to log a
line after the discarded write and assert it's reached — hangs on the
unpatched code (module mode), passes with the fix.
- `TestConnectionAbort` still passes, confirming a genuine client
disconnect is still correctly reported after `fastcgi_finish_request()`.
Fixes https://github.com/php/frankenphp/issues/2548.