取消链接和 SplFileObject

发布于 2024-11-08 13:14:20 字数 114 浏览 4 评论 0原文

是否可以取消文件与 SplFileObject 的链接?

我没有看到关闭底层资源的方法,并且文件句柄是私有的,因此无法以这一目标扩展 SplFileObject。

有什么解决方法吗?

Is it possible to unlink a file from an SplFileObject?

I don't see a method to close the underlying resource, and the file handle is private so one can't extend SplFileObject with that goal in mind.

Are there any workarounds?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

挖个坑埋了你 2024-11-15 13:14:20

我不推荐这样做,因为 PHP 会在幕后为您关闭文件。如果您看一下 php src,ext/spl/spl_directory.c

retval.handle = zend_objects_store_put(intern, 
  (zend_objects_store_dtor_t) zend_objects_destroy_object, 
  (zend_objects_free_object_storage_t) spl_filesystem_object_free_storage, 
   NULL TSRMLS_CC);

设置了一个处理程序,以便在所有引用耗尽时处理对象的清理。现在,我们检查清理处理程序:spl_filesystem_object_free_storage

    case SPL_FS_FILE:
        if (intern->u.file.stream) {
            if (intern->u.file.zcontext) {
/*              zend_list_delref(Z_RESVAL_P(intern->zcontext));*/
            }
            if (!intern->u.file.stream->is_persistent) {
                php_stream_free(intern->u.file.stream, PHP_STREAM_FREE_CLOSE);
            } else {
                php_stream_free(intern->u.file.stream, PHP_STREAM_FREE_CLOSE_PERSISTENT);
            }
            if (intern->u.file.open_mode) {
                efree(intern->u.file.open_mode);
            }
            if (intern->orig_path) {
                efree(intern->orig_path);
            }
        }
        spl_filesystem_file_free_line(intern TSRMLS_CC);
        break;

php_stream_free 调用将为您关闭文件流。如果您取消链接该文件,我无法保证 PHP 将如何处理尝试关闭您刚刚链接的文件句柄。

您必须记住 SplFileObject 为您提供的内容:

SplFileObject extends SplFileInfo implements RecursiveIterator , Traversable , Iterator , SeekableIterator {

它为文件提供了许多基于迭代器的接口。如果您取消链接该文件,它应该迭代什么?您会注意到 close() 也不存在于可用方法中。如果您想做您所说的事情,那么您最好将文件作为资源处理,您可以在其中 close() 句柄并使其可通过 unlink() 使用,避免令人讨厌的副作用。

I would not recommend this, because PHP closes the file behind scenes for you. If you take a look at the php src, ext/spl/spl_directory.c:

retval.handle = zend_objects_store_put(intern, 
  (zend_objects_store_dtor_t) zend_objects_destroy_object, 
  (zend_objects_free_object_storage_t) spl_filesystem_object_free_storage, 
   NULL TSRMLS_CC);

A handler is setup in order to deal with the cleanup of the object when all references have been exhausted. Now, we check the cleanup handler: spl_filesystem_object_free_storage:

    case SPL_FS_FILE:
        if (intern->u.file.stream) {
            if (intern->u.file.zcontext) {
/*              zend_list_delref(Z_RESVAL_P(intern->zcontext));*/
            }
            if (!intern->u.file.stream->is_persistent) {
                php_stream_free(intern->u.file.stream, PHP_STREAM_FREE_CLOSE);
            } else {
                php_stream_free(intern->u.file.stream, PHP_STREAM_FREE_CLOSE_PERSISTENT);
            }
            if (intern->u.file.open_mode) {
                efree(intern->u.file.open_mode);
            }
            if (intern->orig_path) {
                efree(intern->orig_path);
            }
        }
        spl_filesystem_file_free_line(intern TSRMLS_CC);
        break;

The php_stream_free call will close the file stream for you. If you unlink the file, I can't guarantee how PHP will handle trying to close the file handle you just linked.

You have to keep in mind what the SplFileObject provides you:

SplFileObject extends SplFileInfo implements RecursiveIterator , Traversable , Iterator , SeekableIterator {

It's provides many iterator based interfaces for a file. If you unlink the file, what is it supposed to iterate over? You'll notice that close() is not present in the available methods either. If you want to do what you're saying, then you're better off handling the file as a resource, where you can close() the handle and make it usable with unlink(), saving from nasty side effects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文