feature #33003 [Filesystem] Add $suffix argument to tempnam() (jdufresne)

This PR was submitted for the 4.4 branch but it was merged into the 5.1-dev branch instead (closes #33003).

Discussion
----------

[Filesystem] Add $suffix argument to tempnam()

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #33002
| License       | MIT
| Doc PR        | symfony/symfony-docs#12108

**Description**

The `tempnam()` interface was previously:

```php
tempnam($dir, $prefix)
```

This adds a third argument, `$suffix`, that is appended to the filename after the random component. This defaults to `''` for backwards compatibility. This is quite useful when the temporary file is consumed for a specific purpose that expects a suffix.

**Example**

```php
$filesystem->tempnam('/tmp', 'prefix_', '.png');
```

Would create a file like: `/tmp/prefix_abcd1234.png`.

Commits
-------

ef1206964e [Filesystem] Add $suffix argument to tempnam()
This commit is contained in:
Fabien Potencier 2020-02-04 09:10:02 +01:00
commit 7784d9fca2
3 changed files with 22 additions and 3 deletions

View File

@ -10,6 +10,7 @@ CHANGELOG
-----
* support for passing a `null` value to `Filesystem::isAbsolutePath()` is deprecated and will be removed in 5.0
* `tempnam()` now accepts a third argument `$suffix`.
4.3.0
-----

View File

@ -584,15 +584,17 @@ class Filesystem
*
* @param string $prefix The prefix of the generated temporary filename
* Note: Windows uses only the first three characters of prefix
* @param string $suffix The suffix of the generated temporary filename
*
* @return string The new temporary filename (with path), or throw an exception on failure
*/
public function tempnam(string $dir, string $prefix)
public function tempnam(string $dir, string $prefix/*, string $suffix = ''*/)
{
$suffix = \func_num_args() > 2 ? func_get_arg(2) : '';
list($scheme, $hierarchy) = $this->getSchemeAndHierarchy($dir);
// If no scheme or scheme is "file" or "gs" (Google Cloud) create temp file in local filesystem
if (null === $scheme || 'file' === $scheme || 'gs' === $scheme) {
if ((null === $scheme || 'file' === $scheme || 'gs' === $scheme) && '' === $suffix) {
$tmpFile = @tempnam($hierarchy, $prefix);
// If tempnam failed or no scheme return the filename otherwise prepend the scheme
@ -610,7 +612,7 @@ class Filesystem
// Loop until we create a valid temp file or have reached 10 attempts
for ($i = 0; $i < 10; ++$i) {
// Create a unique filename
$tmpFile = $dir.'/'.$prefix.uniqid(mt_rand(), true);
$tmpFile = $dir.'/'.$prefix.uniqid(mt_rand(), true).$suffix;
// Use fopen instead of file_exists as some streams do not support stat
// Use mode 'x+' to atomically check existence and create to avoid a TOCTOU vulnerability

View File

@ -1509,6 +1509,22 @@ class FilesystemTest extends FilesystemTestCase
@unlink($filename);
}
public function testTempnamWithSuffix()
{
$dirname = $this->workspace;
$filename = $this->filesystem->tempnam($dirname, 'foo', '.bar');
$this->assertStringEndsWith('.bar', $filename);
$this->assertFileExists($filename);
}
public function testTempnamWithSuffix0()
{
$dirname = $this->workspace;
$filename = $this->filesystem->tempnam($dirname, 'foo', '0');
$this->assertStringEndsWith('0', $filename);
$this->assertFileExists($filename);
}
public function testDumpFile()
{
$filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo'.\DIRECTORY_SEPARATOR.'baz.txt';