NotionCommotion Posted April 6, 2023 Share Posted April 6, 2023 (edited) I will be using exec() to execute an external program which requires a file output path and will create a file located at that path, and the file is only needed during the execution of the PHP script and should be deleted after the script ends. Good or bad idea? If bad, why? Thanks public function tmpFile():string { return stream_get_meta_data(tmpfile())['uri']; } EDIT - Does "when the script ends" happen about the same time as the class's destructor? Quote The file is automatically removed when closed (for example, by calling fclose(), or when there are no remaining references to the file handle returned by tmpfile()), or when the script ends. Caution If the script terminates unexpectedly, the temporary file may not be deleted. Edited April 6, 2023 by NotionCommotion Quote Link to comment Share on other sites More sharing options...
requinix Posted April 6, 2023 Share Posted April 6, 2023 Why do it that way since all you're doing is reinventing tempnam? 1 hour ago, NotionCommotion said: Does "when the script ends" happen about the same time as the class's destructor? Yes, but you missed the important part: "when there are no remaining references to the file handle". Which is exactly the case when you use the handle, call stream_get_meta_data on it, and then forget the handle existed. Quote Link to comment Share on other sites More sharing options...
kicken Posted April 6, 2023 Share Posted April 6, 2023 If you need an actual file path, then tempnam() is the way to go. tmpfile is for if you need a temporary file resource, just a shortcut essentially for doing fopen('php://temp', 'w+');. As an example, I have a html2pdf class that generates some temp files and calls an external program to generate the PDF. This is how that is coded (roughly). public function generatePdf(){ $pdf = null; try { $source = tempnam(sys_get_temp_dir(), 'htmlpdf'); $destination = tempnam(sys_get_temp_dir(), 'htmlpdf'); file_put_contents($source, $this->html); $cmd = $this->createCommandLine($source, $destination); exec($cmd, $output, $ret); if ($ret !== 0){ throw new \RuntimeException('Failed to generate PDF with command [' . $cmd . '] Output: ' . implode(PHP_EOL, $output)); } $pdf = file_get_contents($destination); } finally { unlink($source); unlink($destination); } return $pdf; } Generate the two temporary file locations, execute the command, then read the content out of the file. The temporary files are then cleaned up using a finally clause which will run whether the function when the function exits, whether that be by a successful return or by throwing an exception. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted April 6, 2023 Author Share Posted April 6, 2023 1 hour ago, requinix said: Why do it that way since all you're doing is reinventing tempnam? Yes, but you missed the important part: "when there are no remaining references to the file handle". Which is exactly the case when you use the handle, call stream_get_meta_data on it, and then forget the handle existed. I didn't think I was quite reinventing tempnam(). tempnam() doesn't delete the file when complete, correct? The example in the doc shows unlinking($tmpfname). However, if calling stream_get_meta_data() deletes the file and I just create it back, and the PHP no longer thinks it is responsible to delete it, suppose I am reinventing. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted April 6, 2023 Author Share Posted April 6, 2023 43 minutes ago, kicken said: If you need an actual file path, then tempnam() is the way to go. tmpfile is for if you need a temporary file resource, just a shortcut essentially for doing fopen('php://temp', 'w+');. As an example, I have a html2pdf class that generates some temp files and calls an external program to generate the PDF. This is how that is coded (roughly). public function generatePdf(){ $pdf = null; try { $source = tempnam(sys_get_temp_dir(), 'htmlpdf'); $destination = tempnam(sys_get_temp_dir(), 'htmlpdf'); file_put_contents($source, $this->html); $cmd = $this->createCommandLine($source, $destination); exec($cmd, $output, $ret); if ($ret !== 0){ throw new \RuntimeException('Failed to generate PDF with command [' . $cmd . '] Output: ' . implode(PHP_EOL, $output)); } $pdf = file_get_contents($destination); } finally { unlink($source); unlink($destination); } return $pdf; } Generate the two temporary file locations, execute the command, then read the content out of the file. The temporary files are then cleaned up using a finally clause which will run whether the function when the function exits, whether that be by a successful return or by throwing an exception. Thanks kicken, Was just trying to get out of the measly two unlink statements, and will stop trying. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.