RecursiveDirectoryIterator throws UnexpectedValueException on "Too many open files" - php

The following code:
$zip = new ZipArchive();
if ($zip->open('./archive.zip', ZIPARCHIVE::CREATE) !== TRUE) {
die ("Could not open archive");
}
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("./folder/"));
foreach ($iterator as $key => $value) {
try {
$zip->addFile(realpath($key), $key);
echo "'$key' successfully added.\n";
} catch (Exception $e) {
echo "ERROR: Could not add the file '$key': $e\n";
}
}
$zip->close();
Throws the following exception if there are too many files in a sub-folder which you're trying to iterate over:
Uncaught exception 'UnexpectedValueException' with message 'RecursiveDirectoryIterator::__construct(./some/path/): failed to open dir: Too many open files' in /some/other/path/zip.php:24
Stack trace:
#0 [internal function]: RecursiveDirectoryIterator->__construct('./some/path/')
#1 /some/other/path/zip.php(24): RecursiveDirectoryIterator->getChildren()
#2 {main}
thrown in /some/other/path/zip.php on line 24
How can you successfully iterate over a large amount of folders and files without experiencing this exception?

Simply by converting the iterator to an array with the iterator_to_array function, it seems like you can iterate over as many files as you'd like:
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("./folder/"));
$files = iterator_to_array($iterator, true);
// iterate over the directory
// add each file found to the archive
foreach ($files as $key => $value) {
try {
$zip->addFile(realpath($key), $key);
echo "'$key' successfully added.\n";
} catch (Exception $e) {
echo "ERROR: Could not add the file '$key': $e\n";
}
}

Related

How to translate the content of my ODT file in any language without losing the quality of the document in PHP?

I am trying to translate my ODT file into any language. But I can't do it. Can you help me?
I think the problem comes from this comment in my code that I have added down:
Here is the comment:
// Re-pack the translated files into a new ODT file
Here is the error:
[01-Feb-2023 07:29:51 UTC] PHP Warning: ZipArchive::close(): Read
error: Is a directory in
/home/bloggors/translatedocs.bloggors.com/controller/test.php on line
57
Here is my code:
<?php
require_once 'includes/init.php';
// Load the ODT file into a ZipArchive object
$zip = new ZipArchive;
$res = $zip->open('input.odt');
if ($res === TRUE) {
$zip->extractTo('input_extracted/');
if (!$zip->close()) {
echo "Error: could not close the archive.";
}
} else {
echo "Error opening the archive: " . $res;
}
// Load the content.xml file into a SimpleXML object
if (file_exists('input_extracted/content.xml')) {
$xml = simplexml_load_file('input_extracted/content.xml');
} else {
echo "Error: could not find content.xml in the extracted archive.";
}
// Translate the text in the SimpleXML object
foreach ($xml->xpath('//text:p') as $paragraph) {
$translatedText = translate($paragraph, 'la', 'fr');
$paragraph[0] = $translatedText;
}
// Save the translated SimpleXML object to a file
if ($xml->asXML('input_extracted/content_translated.xml')) {
// Replace the original content.xml file with the translated one
if (unlink('input_extracted/content.xml')) {
if (!rename('input_extracted/content_translated.xml', 'input_extracted/content.xml')) {
echo "Error: could not rename content_translated.xml to content.xml.";
}
} else {
echo "Error: could not delete content.xml.";
}
} else {
echo "Error: could not save content_translated.xml.";
}
// Re-pack the translated files into a new ODT file
$zip = new ZipArchive;
$res = $zip->open('output.odt', ZipArchive::CREATE);
if ($res === TRUE) {
$dir = opendir('input_extracted/');
while ($file = readdir($dir)) {
if ($file != '.' && $file != '..') {
$zip->addFile('input_extracted/' . $file, $file);
}
}
closedir($dir);
if (!$zip->close()) {
echo "Error: could not close the archive.";
}
} else {
echo "Error opening the archive: " . $res;
}
Any help would be greatly appreciated

Directory is Different When I Run PHP Script IN Scheduled Tasks Of Plesk

I use this clear.php script that remove all files and folders in correct clear directory:
<?php
function deleteDir($dirPath) {
if (! is_dir($dirPath)) {
throw new InvalidArgumentException("$dirPath must be a directory");
}
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
$dirPath .= '/';
}
$files = glob($dirPath . '*', GLOB_MARK);
foreach ($files as $file) {
if (is_dir($file)) {
deleteDir($file);rmdir($file);
} else {
unlink($file);
}
}
}
deleteDir('clear');
?>
when i run the code mydomain.com/clear.php it work and remove all files and folders but when i create a Scheduled Tasks in plesk and use this code it shows:
Task "httpdocs/clear.php" completed with error in 0 seconds. See
details
and when i click the see details it shows:
Task "httpdocs/clear.php" completed with error in 0 seconds, output:
PHP Fatal error: Uncaught InvalidArgumentException: clear must be a directory in /var/www/vhosts/domain_name.com/httpdocs/clear.php:4
Stack trace:
#0 /var/www/vhosts/domain_name.com/httpdocs/clear.php(19): deleteDir('clear')
#1 {main}
thrown in /var/www/vhosts/domain_name.com/httpdocs/clear.php on line 4

Fatal error: Uncaught exception 'UnexpectedValueException' with message 'RecursiveDirectoryIterator::__construct(public/user_/,public/user_/)

I am getting this error while using the RecursiveDirectoryIterator.
Fatal error: Uncaught exception 'UnexpectedValueException' with
message
'RecursiveDirectoryIterator::__construct(public/user_/,public/user_/):
The system cannot find the path specified. (code: 3)' in
D:\xam\htdocs\s\upload.php:101 Stack trace: #0
D:\xam\htdocs\s\upload.php(101):
RecursiveDirectoryIterator->__construct('public/user_/') #1
D:\xam\htdocs\s\upload.php(138): dirSize('public/user_/') #2 {main}
thrown in D:\xam\htdocs\s\upload.php on line 101
Here is the code i am using.
function dirSize($directory) {
$size = 0;
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)) as $file) {
$size+=$file->getSize();
}
return $size;
}
Please help!!!
There is a limited context here to see what is going wrong. However it would appear that your giving a directory to D:\xam\htdocs\s\upload.php that is not valid to start the iteration and find the size.
The try/catch option would stop it from throwing an error and failing
function dirSize($directory) {
$size = 0;
try {
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)) as $file) {
$size += $file->getSize();
}
} catch(Exception $e) {
echo "Error: " . $e;
echo "On: " . $directory;
}
return $size;
}

Using DirectoryIterator to loop through a D: drive directory

I am trying to loop through this directory:
$path = "D:\\import\\statsummary\\";
Here is my code:
$path = "D:\\import\\statsummary\\";
//$path = "C:\\test";
//function load_csv($path, $filename){
if(is_null($filename)){
header('Content-type: text/plain');
$output = array();
foreach (new DirectoryIterator($path) as $file){
if($file->isFile()){
$output[] = $i++ . " " . $file->getFileName() . "\n";
$output[] = file($file->getPathName());
$output[] = "\n------------\n";
}
}
}
echo implode('', $output);
When I run this script, I get this error:
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'DirectoryIterator::__construct(D:\import\statsummary\,D:\import\statsummary\): Access is denied. (code: 5)' in C:\inetpub\wwwroot\include\file_importer.php:10
Stack trace:
#0 C:\inetpub\wwwroot\include\file_importer.php(10): DirectoryIterator->__construct('D:\import\...')
#1 {main}
thrown in C:\inetpub\wwwroot\include\file_importer.php on line 10
But when I change it to a test directory on my C:\ drive, it runs just fine. I've even created a username to run PHP as directed in this post:
php - Unable to connect to network share - Stack Overflow
Based on the DirectoryIterator class, something like this should work:
<?php
$path = "D:/import/statsummary";
$output=array();
$iterator = new DirectoryIterator(path);
foreach ($iterator as $fileinfo) {
if ($fileinfo->isFile()) {
$filename= $fileinfo->getFilename();
$path=$fileinfo->getPathname();
$output[][$filename]=$path;
}
}
print_r($output);
?>
Update
Since you're getting access denied, you'll need to run the command prompt (CMD) window as Administrator more than likely. If this is on a link (lnk) you can change the permissions in the link settings.
For instance if you right-click on the shortcut for cmd as select properties, you would go to shortcut>advanced>Run as Administrator.

Fatal error: Uncaught exception 'RuntimeException'

I'm running PHP version 5.2.11
When I run the function below:
function get_dirs($path = '.') {
$dirs = array();
foreach (new DirectoryIterator($path) as $file) { // This is line 462.
if ($file->isDir() && !$file->isDot()) {
$dirs[] = $file->getFilename();
}
}
return $dirs;
}
I get this error:
Fatal error: Uncaught exception 'RuntimeException' with message 'DirectoryIterator::__construct(/home/test/test.com/wp-content/themes/mytheme/images) [<a href='directoryiterator.--construct'>directoryiterator.--construct</a>]: failed to open dir: No such file or directory' in /home/test/test.com/testing123/wp-content/themes/mytheme/functions.php:462 Stack trace: #0 /home/test/test.com/testing123/wp-content/themes/mytheme/functions.php(462): DirectoryIterator->__construct('/home/test/wie...') #1 /home/test/test.com/testing123/wp-content/themes/mytheme/functions.php(31): get_dirs('/home/test/wie...') #2 /home/test/test.com/testing123/wp-settings.php(717): include('/home/test/wie...') #3 /home/test/test.com/testing123/wp-config.php(76): require_once('/home/test/wie...') #4 /home/test/test.com/testing123/wp-load.php(30): require_once('/home/test/wie...') #5 /home/test/test.com/testing123 in /home/test/test.com/testing123/wp-content/themes/mytheme/functions.php on line 462
UPDATE: The problem here I've found is that the theme was installed under a virtual directory off the main URL. My scripts are expecting that the theme is installed off the main root url.
For example, the theme in this case was installed at: http://www.example.com/testing123/wp-content/themes/mytheme
However, I'm expecting this: http://www.example.com/wp-content/themes/mytheme
AND SO...
My path function fails since it does not take into consideration that it could be installed under a virtual directory.
How could I account for this scenario in my feeding of this function?
$mydir = get_dirs("$_SERVER[DOCUMENT_ROOT]/wp-content/themes/mytheme/images");
function get_dirs ($path = '.') {
$dirs = array();
foreach (new DirectoryIterator($path) as $file) {
if ($file->isDir() && !$file->isDot()) {
$dirs[] = $file->getFilename();
}
}
return $dirs;
}
Enclose it in a try-catch block?
function get_dirs($path = '.') {
$dirs = array();
try{
foreach (new DirectoryIterator($path) as $file) { //this is line 462
if ($file->isDir() && !$file->isDot()) {
$dirs[] = $file->getFilename();
}
}
} catch(Exception $e) {
//log exception or process silently
//just for test
echo $e;
}
return $dirs;
The class is there, but apparently your images directory is not:
/home/test/test.com/wp-content/themes/mytheme/images
The key part of the message being:
failed to open dir: No such file or directory
Or, if it is there, PHP doesn't have permissions to read from it.
It looks like the third line is telling you that the directory cannot be found:
failed to open dir: No such file or directory
I would check your path from the script being called and adjust that appropriately

Categories