-
Notifications
You must be signed in to change notification settings - Fork 8k
[RFC]: Add file_descriptor() function to retrieve the file descriptor of a PHP Stream #10342
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
| * It is only used here so that the buffered data warning is not displayed. | ||
| */ | ||
| if (php_stream_can_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL) == FAILURE) { | ||
| zend_argument_type_error(1, "cannot represent as a file descriptor"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| zend_argument_type_error(1, "cannot represent as a file descriptor"); | |
| zend_argument_type_error(1, "cannot be represented as a file descriptor"); |
|
it think we miss a test case for closed resources, i.e: $fp = fopen('somefile.txt', 'wb+');
fclose($fp);
try {
var_dump(file_descriptor($fp));
} catch ( ... ) {
...
} |
|
|
||
| php_stream_from_zval(stream, zsrc); | ||
|
|
||
| /* TODO Should support streams that can be cast with PHP_STREAM_AS_FD_FOR_SELECT ? */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general PHP_STREAM_AS_FD should be supported if PHP_STREAM_AS_FD_FOR_SELECT which should be the case for all core stream wrappers - I just checked and don't see a case where it would be different. So I wouldn't bother with checking PHP_STREAM_AS_FD_FOR_SELECT as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks good in general. The test failure seems related as you probably know.
|
@Girgias Any updates with this PR? |
Requires an RFC and people didn't seem to find the motivation strong enough. What is the reason you want this function? As it may help me push this through the RFC process. |
|
@Girgias I was integrating a C function into my PHP app using FFI. The C function requires a raw OS file descriptor. For now, I'd tried the mentioned library php-fileno, It works but seems like it is extremely redundant and something like file_descriptor() is needed to be native in PHP. Also, I used AI to get me some work around, cuz using a composer package is not the ideal thing in my case [app with only two files, x.php, x.c that needs to be portable as much as it can be]. I ended up with something like: function get_real_fd($resource) {
// 1. Get the Inode of the PHP resource
$stat = fstat($resource);
if (!isset($stat['ino'])) return false;
$target_inode = $stat['ino'];
// 2. Scan /proc/self/fd to find the matching FD
$fds = scandir('/proc/self/fd');
foreach ($fds as $fd) {
if ($fd === '.' || $fd === '..') continue;
// Stat the FD link to see if it matches our resource's inode
$fd_stat = stat("/proc/self/fd/$fd");
if ($fd_stat && $fd_stat['ino'] == $target_inode) {
return (int)$fd;
}
}
return false;
}It works too, the good thing is that this will be working across most known Linux distros. But, it obviously seems like it won't work on Windows, macOS ... etc. |
RFC: https://wiki.php.net/rfc/file-descriptor-function
The purpose of this function is to retrieve the underlying file descriptors for PHP streams when they exist.
It is currently possible to achieve this result by using FFI and stubbing the Zend engine (see: https://github.com/ppelisset/php-fileno).
This can be needed when trying to interact with a USB device, as this is the use case @ppelisset has.
Test should be based of #10173 when it gets merged.