【问题标题】:Unlink and SplFileObject取消链接和 SplFileObject
【发布时间】:2011-05-19 23:59:40
【问题描述】:

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

我没有看到关闭底层资源的方法,而且文件句柄是私有的,因此无法在考虑到该目标的情况下扩展 SplFileObject。

有什么解决方法吗?

【问题讨论】:

  • 您可以使用SplFileObject::getPathName() 获取路径,取消设置SplFileObject(我假设 关闭句柄)然后unlink 您获得的路径。跨度>
  • 取消链接文件不需要关闭所有文件句柄。即使文件名已被删除,您仍然可以很好地读取和写入文件。

标签: php file unlink splfileobject


【解决方案1】:

我不建议这样做,因为 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 {

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多