getID3 icon indicating copy to clipboard operation
getID3 copied to clipboard

`analyze()` locked the file and can't delete on PHP 8.0+

Open ve3 opened this issue 1 year ago • 1 comments

getID3 version 1.9.23, 2.0.x-dev on 2024-12-14

Test with this code.

<?php

require 'vendor/autoload.php';


$fileName = 'test.txt';
$folderPath = __DIR__ . DIRECTORY_SEPARATOR . 'test';
$fileFullPath = $folderPath . DIRECTORY_SEPARATOR . $fileName;

// prepare folder.
if (!file_exists($folderPath)) {
    $umask = umask(0);
    mkdir($folderPath, 0755, true);
    umask($umask);
}

// create false media file.
file_put_contents($fileFullPath, 'hello');
assert(file_exists($fileFullPath), 'File is not created.');

$GetId3 = new \getID3();
$fileInfo = $GetId3->analyze($fileFullPath);
unset($GetId3);

// delete file.
assert(true === unlink($fileFullPath), 'Failed to delete file.');
assert(!file_exists($fileFullPath), 'File still exists.');
assert(file_exists($folderPath) && is_dir($folderPath), 'Parent folder is not exists.');

// check by list files in testing folder.
$scandir = scandir($folderPath);
foreach ($scandir as $file) {
    if ('.' === $file || '..' === $file) {
        continue;
    }
    echo $file . ' (' . __LINE__ . ')' . "\n";
}
$Fsi = new \DirectoryIterator($folderPath);
foreach ($Fsi as $File) {
    if ($File->isDot()) {
        continue;
    }
    echo $File . ' (' . __LINE__ . ')' . "\n";
}
unset($file, $File, $Fsi, $scandir);

// delete folder.
assert(!file_exists($fileFullPath), 'File still exists.');
$deleteFolderResult = rmdir($folderPath);
assert(true === $deleteFolderResult, 'Failed to delete folder.');
unset($deleteFolderResult);

echo 'End test.' . PHP_EOL . PHP_EOL;

test.php

After run in the command php test.php on PHP 8.0 or newer the result will be:

test.txt (35) test.txt (42)

Warning: rmdir(D:\wwwroot_test\getid3\test): Directory not empty in D:\wwwroot_test\getid3\test.php on line 47

However, the file gets deleted after command ended but not by the code unlink().

The code above is working fine on PHP 7.4.latest or older.

ve3 avatar Dec 14 '24 03:12 ve3

I think you forgot to properly closed one or more fclose().

Add this code before delete the file now the file gets deleted properly.

// delete any resource that were left opened by `fopen()`.
$resources = get_resources();
foreach ($resources as $rs) {
    $resourceType = get_resource_type($rs);
    if ('stream' === strtolower($resourceType)) {
        $streamMeta = stream_get_meta_data($rs);
        if (isset($streamMeta['wrapper_type']) && 'plainfile' === strtolower($streamMeta['wrapper_type'])) {
            fclose($rs);
        }
    }
    unset($resourceType, $streamMeta);
}
unset($rs, $resources);

ve3 avatar Dec 14 '24 05:12 ve3