天道酬勤,学无止境

Unlink and 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?

评论

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.

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 如何从PHP中的csv文件中提取数据(How to extract data from csv file in PHP)
    问题 我有一个看起来像这样的csv文件 $lines[0] = "text, with commas", "another text", 123, "text",5; $lines[1] = "some without commas", "another text", 123, "text"; $lines[2] = "some text with commas or no",, 123, "text"; 我想要一张桌子: $t[0] = array("text, with commas", "another text", "123", "text","5"); $t[1] = array("some without commas", "another text", "123", "text"); $t[2] = array("some text, with comma,s or no", NULL , "123", "text"); 如果我使用split($lines[0],",")我将得到"text" ,"with commas" ...有什么优雅的方法吗? 回答1 您可以使用fgetcsv解析CSV文件,而不必担心自己解析。 PHP手册中的示例: $row = 1; if (($handle = fopen("test.csv", "r")) !== FALSE) {
  • $file->eof() 在 'r' 模式下使用 PHP 的 SplFileObject 时总是返回 false($file->eof() always returning false when using PHP's SplFileObject in 'r' mode)
    问题 为什么我的 PHP 脚本挂了? $path = tempnam(sys_get_temp_dir(), '').'.txt'; $fileInfo = new \SplFileInfo($path); $fileObject = $fileInfo->openFile('a'); $fileObject->fwrite("test line\n"); $fileObject2 = $fileInfo->openFile('r'); var_dump(file_exists($path)); // bool(true) var_dump(file_get_contents($path)); // string(10) "test line // " var_dump(iterator_count($fileObject2)); // Hangs on this 如果我删除最后一行( iterator_count(... )并将其替换为: $i = 0; $fileObject2->rewind(); while (!$fileObject2->eof()) { var_dump($fileObject2->eof()); var_dump($i++); $fileObject2->next(); } // Output: // bool(false) // int(0) //
  • PHP:是否可以从文件内容(字符串)创建 SplFileObject 对象?(PHP: Is it possible to create a SplFileObject object from file contents (string)?)
    问题 例如: $contents = file_get_contents(image.png); 是否可以从 $contents 创建一个 SplFileObject 对象? 谢谢! 回答1 php 有一些特殊的流包装器,可以让您重新使用各种文件系统功能 $contents = 'i am a string'; $file = 'php://memory'; //full memory buffering mode //$file = 'php://temp/maxmemory:1048576'; //partial memory buffering mode. Tries to use memory, but over 1MB will automatically page the excess to a file. $o = new SplFileObject($file, 'w+'); $o->fwrite($contents); 不过,您不需要使用 SplFileObject 来使用这些包装器; 你可以使用 fopen 和 fwrite 代替。
  • SPLFileObject 是原子的吗?(Is SPLFileObject atomic?)
    问题 我想知道 PHP SPLFileObject 的方法是否是原子的(例如线程安全的)? 如果不是,我将实现我自己的类,它将使用flock() ,但这是否足够? flock 函数真的是线程安全的吗? 如果在fopen()文件之后但在flock()之前发生冲突怎么办? 回答1 我认为您滥用了“线程安全”一词。 线程安全(主要)是关于线程代码中的共享资源。 PHP 没有线程,并且文件句柄不是共享资源。 不过,文件是共享资源。 我认为您正在寻找术语“竞争条件”。 如果在fopen()文件之后但在flock()之前发生冲突怎么办? 如果您不使用 SPLFileObject,也会发生同样的事情。 只要确保你永远不要打开+截断,总是打开+附加,然后在你拥有锁后截断。 如果您已经了解文件打开和锁定竞争条件的工作原理,这应该是标准程序。
  • PHP LimitIterator 失败(“不支持查找”+“无法倒带文件”)(PHP LimitIterator fails (“Does not support seeking” + “Cannot rewind file”))
    问题 我使用SplFileObject和LimitIterator从大文件的位置 x 到 y 读取内容。 这在使用像/home/devel/stuff/myfile.log这样的文件路径时非常/home/devel/stuff/myfile.log 。 当使用像http://mydomain.com:8090/devel/stuff/myfile.log这样的路径时,它不起作用。 然而路径是正确的。 使用绝对路径时会失败吗? 错误消息是: PHP Warning: SplFileObject::rewind() [<a href='splfileobject.rewind'>splfileobject.rewind</a>]: stream does not support seeking in ... PHP Fatal error: Uncaught exception 'RuntimeException' with message 'Cannot rewind file ...' 完整代码: // $pStrFile contains the valid (yes!) path $oFile = new SplFileObject($pStrFile); // $nFrom = 80 and $nLines = 30 $fileIterator = new
  • 用最少的内存密集型方式读取PHP中的文件(Least memory intensive way to read a file in PHP)
    问题 我正在使用Php中的file()函数读取包含约5万行的文件。 但是,由于文件的内容以数组形式存储在内存中,因此发出内存不足错误。 还有其他办法吗? 同样,存储的行的长度是可变的。 这是代码。 另外文件是700kB而不是mB。 private static function readScoreFile($scoreFile) { $file = file($scoreFile); $relations = array(); for($i = 1; $i < count($file); $i++) { $relation = explode("\t",trim($file[$i])); $relation = array( 'pwId_1' => $relation[0], 'pwId_2' => $relation[1], 'score' => $relation[2], ); if($relation['score'] > 0) { $relations[] = $relation; } } unset($file); return $relations; } 回答1 使用fopen,fread和fclose顺序读取文件: $handle = fopen($filename, 'r'); if ($handle) { while (!feof($handle)) { echo
  • SplFileObject 错误无法打开流:没有这样的文件或目录(SplFileObject error failed to open stream: No such file or directory)
    问题 我正在尝试在 symfony2 中实现存折网络服务并遵循这个存折包,我的控制器看起来像这样 if ($form->isValid()) { // Create an event ticket $pass = new EventTicket("1234567890", "The Beat Goes On"); $pass->setBackgroundColor('rgb(60, 65, 76)'); $pass->setLogoText('Apple Inc.'); // Create pass structure $structure = new Structure(); // Add primary field $primary = new Field('event', 'The Beat Goes On'); $primary->setLabel('Event'); $structure->addPrimaryField($primary); // Add secondary field $secondary = new Field('location', 'Moscone West'); $secondary->setLabel('Location'); $structure->addSecondaryField($secondary); // Add
  • 如何使用PHP获取CSV文件中的总行数?(How can I get the total number of rows in a CSV file with PHP?)
    问题 如何使用PHP获取CSV文件中的总行数? 我正在使用此方法,但可以使其正常工作。 if (($fp = fopen("test.csv", "r")) !== FALSE) { while (($record = fgetcsv($fp)) !== FALSE) { $row++; } echo $row; } 回答1 这是另一个使用file()将整个文件读入数组,自动解析新行等的选项: $fp = file('test.csv'); echo count($fp); 另外,从PHP5开始,如果您要执行以下操作,则可以传入FILE_SKIP_EMPTY_LINES ...来跳过空行: $fp = file('test.csv', FILE_SKIP_EMPTY_LINES); 手册: http : //php.net/manual/zh/function.file.php 回答2 使用SplFileObject创建一个新的文件引用: $file = new SplFileObject('test.csv', 'r'); 尝试seek最高的Int PHP可以处理的内容: $file->seek(PHP_INT_MAX); 然后实际上它将寻求文件中可能的最高行,这是您的最后一行,最后一行+ 1等于您的总行数: echo $file->key() + 1; 棘手
  • SplFileObject error failed to open stream: No such file or directory
    i am trying to implement passbook web service in symfony2 and following this passbook bundle and my controller looks like this if ($form->isValid()) { // Create an event ticket $pass = new EventTicket("1234567890", "The Beat Goes On"); $pass->setBackgroundColor('rgb(60, 65, 76)'); $pass->setLogoText('Apple Inc.'); // Create pass structure $structure = new Structure(); // Add primary field $primary = new Field('event', 'The Beat Goes On'); $primary->setLabel('Event'); $structure->addPrimaryField($primary); // Add secondary field $secondary = new Field('location', 'Moscone West'); $secondary-
  • 将制表符分隔的文本文件转换为 XML(Convert Tab delimited text file to XML)
    问题 我想知道是否有一种可接受的方法可以将制表符分隔的文本文件转换为 XML,以便可以将其导入 Adob​​e Flex。 我更愿意使用 PHP 来实现这一点。 谢谢 编辑: 我要转换的制表符分隔文本文件的格式为 Refnumber Location Name Age 123 North America Steve 32 我希望转换为 <data> <refnumber> 123 </refnumber> <location> North America </location> <name> Steve </name> <age> 32 </age> </data> 回答1 您可以逐行迭代文件并使用 XMLWriter 写入内容 XmlWriter 示例(演示) $xmlWriter = new XMLWriter(); $xmlWriter->openUri('/path/to/destination.xml'); $xmlWriter->setIndent(true); $xmlWriter->startDocument('1.0', 'UTF-8'); $xmlWriter->startElement('root'); $tsvFile = new SplFileObject('filename.tsv'); $tsvFile->setFlags(SplFileObject
  • PHP LimitIterator fails (“Does not support seeking” + “Cannot rewind file”)
    I use SplFileObject and LimitIterator to read content from position x till y of a big file. This works perfectly when using a file path like /home/devel/stuff/myfile.log. When using a path like http://mydomain.com:8090/devel/stuff/myfile.log it does not work. The path is correct however. Does this fail when using absolute paths? The error messages are: PHP Warning: SplFileObject::rewind() [<a href='splfileobject.rewind'>splfileobject.rewind</a>]: stream does not support seeking in ... PHP Fatal error: Uncaught exception 'RuntimeException' with message 'Cannot rewind file ...' Full code: //
  • PHP: Is it possible to create a SplFileObject object from file contents (string)?
    For example: $contents = file_get_contents(image.png); Is it possible to create a SplFileObject object from $contents? Thanks!
  • Is SPLFileObject atomic?
    I'm wondering whether methods of PHPs SPLFileObject are atomic (e.g. thread-safe) or not? If they aren't, I'll implement my own class, which will use flock(), but is this enough? Is the flock function really thread-safe? What if the collision occurs after I fopen() the file, but before I flock() it?
  • $file->eof() always returning false when using PHP's SplFileObject in 'r' mode
    Why is my PHP script hanging? $path = tempnam(sys_get_temp_dir(), '').'.txt'; $fileInfo = new \SplFileInfo($path); $fileObject = $fileInfo->openFile('a'); $fileObject->fwrite("test line\n"); $fileObject2 = $fileInfo->openFile('r'); var_dump(file_exists($path)); // bool(true) var_dump(file_get_contents($path)); // string(10) "test line // " var_dump(iterator_count($fileObject2)); // Hangs on this If I delete the last line (iterator_count(...) and replace it with this: $i = 0; $fileObject2->rewind(); while (!$fileObject2->eof()) { var_dump($fileObject2->eof()); var_dump($i++); $fileObject2->next
  • 如何逐行读取大文件?(How to read a large file line by line?)
    问题 我想逐行读取文件,但没有完全将其加载到内存中。 我的文件太大,无法在内存中打开,如果尝试这样做,我总是会走出内存错误。 文件大小为1 GB。 回答1 您可以使用fgets()函数逐行读取文件: $handle = fopen("inputfile.txt", "r"); if ($handle) { while (($line = fgets($handle)) !== false) { // process the line read. } fclose($handle); } else { // error opening the file. } 回答2 if ($file = fopen("file.txt", "r")) { while(!feof($file)) { $line = fgets($file); # do same stuff with the $line } fclose($file); } 回答3 您可以将面向对象的接口类用于文件-SplFileObject http://php.net/manual/zh-CN/splfileobject.fgets.php(PHP 5> = 5.1.0) <?php $file = new SplFileObject("file.txt"); // Loop until we reach the end of
  • 将 CSV 处理为带有键列标题的数组(Process CSV Into Array With Column Headings For Key)
    问题 我有一个 CSV,第一行包含字段名称。 示例数据是... "Make","Model","Note" "Chevy","1500","loaded" "Chevy","2500","" "Chevy","","loaded" 我需要将数据格式化为键值对数组,其中键名是列标题。 我想第 1 行会是这样的: $array = [ "Make" => "Chevy", "Model" => "1500", "Note" => "loaded" ]; ...第 2 行... $array = [ "Make" => "Chevy", "Model" => "1500", "Note" => "" ]; ...和第 3 行... $array = [ "Make" => "Chevy", "Model" => "", "Note" => "loaded" ]; 除了静态之外,我不知道如何做到这一点 - 问题是具有关联数据的列可能会从一个文件更改为下一个文件...重新排列、删除或添加的列。 非常感谢您的想法。 回答1 $all_rows = array(); $header = fgetcsv($file); while ($row = fgetcsv($file)) { $all_rows[] = array_combine($header, $row); } print_r($all
  • php 使用SplFileObject读取大文件(日志文件)
    荆轲刺秦王 SPL是Standard PHP Library(PHP标准库)的缩写 大神文档: http://www.ruanyifeng.com/blog/2008/07/php_spl_notes.html 官方文档: https://www.php.net/manual/zh/book.spl.php 来源:https://blog.csdn.net/qq_38350907/article/details/116130336
  • Docusign REST API: Downloading document to string
    I am building an app using the docusign API and PHP. I have most of this working except I cannot figure out how to download the document. I have been searching on this site and on the Docusign site. Docusign has an example here, that shows how to get a list of docs in PHP, but the downloading does not have a PHP example. In the Docusign REST API docs they explain the method here. But this says the response is "PDF File". In my sample code below, I have tried to put the contents into a file, but it creates and empty file. If I print_r($data), I get this: SplFileObject Object ( [pathName
  • 从文件中读取第一行的最快方法(Quickest Way to Read First Line from File)
    问题 仅从文件中读取第一行的最快、最简单的方法是什么? 我知道你可以使用file ,但就我而言,浪费时间加载整个文件是没有意义的。 最好是单层。 回答1 好吧,你可以这样做: $f = fopen($file, 'r'); $line = fgets($f); fclose($f); 这不是一行,但如果你把它写成一行,你要么被错误检查搞砸,要么让资源打开的时间比你需要的时间长,所以我会说保留多行 编辑 如果您绝对知道该文件存在,则可以使用单行: $line = fgets(fopen($file, 'r')); 原因是 PHP 为资源实现了 RAII。 这意味着当文件句柄超出范围时(在这种情况下,在调用 fgets 之后立即发生),它将被关闭。 回答2 $firstline=`head -n1 filename.txt`; 回答3 $line = ''; $file = 'data.txt'; if($f = fopen($file, 'r')){ $line = fgets($f); // read until first newline fclose($f); } echo $line; 回答4 没有人提到 file() 函数给我留下了深刻印象: $line = file($filename)[0]; 或者如果 version_compare(PHP_VERSION, "5.4
  • How to do AJAX with setInterval in Laravel 5.4
    In normal PHP, I can do AJAX and update the page with setInterval as follows: script.js setInterval(function(){ $.get( "fetch_json.php", function( data ) { var jsonData = JSON.parse(data); $.each(jsonData, function(itemKey,itemObject){ // update div without refreshing the page } },1000); fetch_json.php $results_array = []; $file = new SplFileObject("file.csv"); $file->setFlags(SplFileObject::READ_CSV); foreach ($file as $row) { $results_array[] = $row[0]; $results_array[] = $row[1]; $results_array[] = $row[2]; $results_array[] = $row[3]; } echo json_encode($results_array); In Laravel 5.4, I