getID3
getID3 copied to clipboard
`analyze()` locked the file and can't delete on PHP 8.0+
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.
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);