Using php to rename all files in folder - php

new php programmer here. I have been trying to rename all the files in a folder by replacing the extension.
The code I'm using is from the answer to a similar question on SO.
if ($handle = opendir('/public_html/testfolder/')) {
while (false !== ($fileName = readdir($handle))) {
$newName = str_replace(".php",".html",$fileName);
rename($fileName, $newName);
}
closedir($handle);
}
I get no errors when running the code, but no changes are made to the filenames.
Any insight on why this isn't working? My permission settings should allow it.
Thanks in advance.
EDIT: I get a blank page when checking the return value of rename(), now trying something with glob() which might be a better option than opendir...?
EDIT 2: With the 2nd code snippet below, I can print the contents of $newfiles. So the array exists, but the str_replace + rename() snippet fails to change the filename.
$files = glob('testfolder/*');
foreach($files as $newfiles)
{
//This code doesn't work:
$change = str_replace('php','html',$newfiles);
rename($newfiles,$change);
// But printing $newfiles works fine
print_r($newfiles);
}

Here is the simple solution:
PHP Code:
// your folder name, here I am using templates in root
$directory = 'templates/';
foreach (glob($directory."*.html") as $filename) {
$file = realpath($filename);
rename($file, str_replace(".html",".php",$file));
}
Above code will convert all .html file in .php

You're probably working in the wrong directory. Make sure to prefix $fileName and $newName with the directory.
In particular, opendir and readdir don't communicate any information on the present working directory to rename. readdir only returns the file's name, not its path. So you're passing just the file name to rename.
Something like below should work better:
$directory = '/public_html/testfolder/';
if ($handle = opendir($directory)) {
while (false !== ($fileName = readdir($handle))) {
$newName = str_replace(".php",".html",$fileName);
rename($directory . $fileName, $directory . $newName);
}
closedir($handle);
}

Are you sure that
opendir($directory)
works? Have you checked that? Because it seems there might be some Document Root missing here...
I would try
$directory = $_SERVER['DOCUMENT_ROOT'].'public_html/testfolder/';
And then Telgin's solution:
if ($handle = opendir($directory)) {
while (false !== ($fileName = readdir($handle))) {
$newName = str_replace(".php",".html",$fileName);
rename($directory . $fileName, $directory . $newName);
}
closedir($handle);
}

That happens if the file is opened. Then php cannot do any changes to the file.

<?php
$directory = '/var/www/html/myvetrx/media/mydoc/';
if ($handle = opendir($directory)) {
while (false !== ($fileName = readdir($handle))) {
$dd = explode('.', $fileName);
$ss = str_replace('_','-',$dd[0]);
$newfile = strtolower($ss.'.'.$dd[1]);
rename($directory . $fileName, $directory.$newfile);
}
closedir($handle);
}
?>
Thank you so much for the suggestions. it's working for me!

Related

linking directories and files in php

Hello stackoverflow community;
I'm trying to display a few files in a directory using php and coming unstuck:
In my file ('salad') I have three recipe files ('recipe1.txt', recipe2.txt, 'recipe3.txt') and I want to display them so I'm writing the following:
$script = opendir('salad');
while(false !==($file = readdir($script))) {
if (is_file($file)) {
echo "<p>$file</p>";
}
}
Unfortunately this only echos to the screen .DS_store, what am i doing wrong?
You could use this:
<?php
$dir = "/tmp"; // put what suits you here
$dh = opendir($dir);
while (false !== ($filename = readdir($dh))) {
$files[] = $filename;
}
sort($files);
print_r($files);
rsort($files);
echo"$files";
?>
source:
http://php.net/manual/en/function.scandir.php

File renaming using php

Have the following script.
<?php
if ($handle = opendir('files/')) {
while (false !== ($fileName = readdir($handle))) {
$newName = str_replace("SKU#","",$fileName);
rename(fileName, $newName);
}
closedir($handle); } ?>
my script is in the root directory of iss.
inetpub/wwwroot
And I am trying to as a result access the folder files/, which is one level up to wwwroot. Where contains one image called:
"WV1716BNSKU#.zoom.1"
I am using a windows OS, any idea why this is not working, code looks file.
What error do you get? Make sure PHP is setup to display all errors.
Your script will also have to be in the same folder as your files you want to rename as all your paths are relative.
Try this:
if ($handle = opendir('./')){
while (false !== ($fileName = readdir($handle))){
$newName = str_replace("SKU#", "", $fileName);
rename($fileName, $newName);
}
closedir($handle);
}

How to take first file name from a folder and delete it in PHP

I try to make a gallery. In a folder I have some duplicate pictures. I have pictures named: af_160112, af_160113, af_160114. I would like remove this first one. How to take the first picture in a folder and delete it? So far I have known that I should use unlinke($file) function. Thank you for your help.
Solved.
I used:
$files = glob($path_to_gallery . '/*.{jpg,png,gif}', GLOB_BRACE);
foreach($files as $file) {
unlink($file);
break;
}
$path = 'full_path/gallery/';
$dir = opendir($path);
while ($dir && ($file = readdir($dir)) !== false) {
unlink($path.$file);
break;
}

is_dir does not recognize folders

I am trying to make a function that scans a folder for subfolders and then returns
a numeric array with the names of those folders.
This is the code i use for testing. Once i get it to print out the folder names and not just "." and ".." for present and above folder all will be well, and I can finish the function.
<?php
function super_l_getthemes($dir="themes")
{
if ($handle = opendir($dir)) {
echo "Handle: {$handle}\n";
echo "Files:\n";
while (false !== ($file = readdir($handle))) {
echo "{$file}<br>";
}
closedir($handle);
}
?>
The above code works fine, and prints out all the contents of the folder: files, subfolders and the "." and ".."
but if i replace:
while (false !== ($file = readdir($handle))) {
echo "{$file}<br>";
}
with:
while (false !== ($file = readdir($handle))) {
if(file_exists($file) && is_dir($file)){echo "{$file}";}
}
The function only prints "." and ".." , not the two folder names that I'd like it to print.
Any help is appreciated.
You must provide the absolute path to file_exists, otherwise it will look for it in the current execution path.
while (false !== ($file = readdir($handle))) {
$file_path = $dir . DIRECTORY_SEPARATOR . $file;
if (file_exists($file_path) && is_dir($file_path)) {
echo "{$file}";
}
}
The problem with readdir is that it only reads the strings of the named entries inside of the directory.
For instance, if you had file "foo" inside of directory "/path/to/files/", when using readdir on "/path/to/files/", you would eventually come to the string "foo".
Normally this wouldn't be a problem if it were in the same directory as the current working directory of the script, but, since you are reading from an arbitrary director, when you are attempting to inspect the entry (file, directory, whatever), you are calling is_dir on the bare string "foo".
I would try prefixing the name you pull out using readdir with the path to the file.
if ($handle = opendir($dir)) {
echo "Handle: {$handle}\n";
echo "Files:\n";
while ($file = readdir($handle)) {
/*** make $file into an absolute path ***/
$absolute_path = $dir . '/' . $file;
/*** NOW try stat'ing it ***/
if (is_dir($absolute_path)) {
/* it's a directory; do stuff */
}
}
closedir($handle);
}
You need to use:
while (false !== ($file = readdir($handle))) {
if(file_exists($dir.'/'.$file) && is_dir($dir.'/'.$file)){echo "{$file}";}
}
See http://php.net/readdir
If you only want the directories of the starting folder, you can simply do:
glob('/some/path/to/search/in/*', GLOB_ONLYDIR);
which would given you only those foldernames in an array. If you want all directories below a given path, try SPL's RecursiveDirectoryIterator
$fileSystemIterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator('/some/path/to/look/in'),
RecursiveIteratorIterator::SELF_FIRST);
Iterators can be used with foreach:
$directories = array();
foreach($fileSystemIterator as $path => $fileSystemObject) {
if($fileSystemObject->isDir()) {
$directories[] = $path;
}
}
You will then have an array $directories with all directories under the given path.
$files = array();
foreach(new DirectoryIteraror('/path') as $file){
if($file->isDir() /* && !$file->isDot()*/) $files[] = $file->getFilename();
}
[edit: though you wanted to skip the dot, commented it out)
I don't think you need both file_exists and is_dir,
You just need the is_dir function. From the manual:
is_dir Returns TRUE if the filename exists and is a directory, FALSE otherwise.
Use this:
while (false !== ($file = readdir($handle))) {
if(is_dir($file)){echo "{$file}";}
}
is_dir will also check whether it's a relative path or an absolute path.
$directory = scandir($path);
foreach($directory as $a){
if(is_dir($path.$a.'/') && $a != '.' && $a != '..'){
echo $a.'<br/>';
}
}
With the path given as shown, it displays the folders present in the path.
I agree with nuqqsa's solution, however, I'd like to add something to it.
Instead of specifying the path, you can change the current directory instead.
For example,
// open directory handle
// ....
chdir($dir);
while (false !== ($file = readdir($handle)))
if(is_dir($file))
echo $file;
// close directory handle

Why does my zip code not work as expected?

See this question. I can't use that code:
function addFolderToZip($dir, $zipArchive, $zipdir = ''){
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
//Add the directory
$zipArchive->addEmptyDir($dir);
// Loop through all the files
while (($file = readdir($dh)) !== false) {
//If it's a folder, run the function again!
if(!is_file($dir . $file)){
// Skip parent and root directories
if( ($file !== ".") && ($file !== "..")){
addFolderToZip($dir . $file . "/", $zipArchive, $zipdir . $file . "/");
}
}else{
// Add the files
$zipArchive->addFile($dir . $file, $zipdir . $file);
}
}
}
Please write an example for me. The second problem is too complex.
When I use addfile function it will add and appear in the archive as a file and this great. Now when I use:
$z = new ZipArchive();
$z->open('test.zip')
for ($i=0; $i< $z->numFiles;$i++) {
$aZipDtls = $z->statIndex($i);
echo $aZipDtls['name'];
}
it now shows if I add a file in folder like that:
$zip->addFile('/path/to/index.txt', 'dir/newname.txt');
it show in the Winrar soft a dir then a file but in the code it shows it as one file.
Like that in winrar:
dir/
dir/newname.txt
In my PHP system, just only show one file without its dir, like that:
dir/newname.txt
This mean it's impossible to add a new file in a dir.
Difficult to know what you want, but here goes:
<?php
$zip = new ZipArchive();
$zip->open('test.zip');
$zip->addFile('/path/to/newname.txt','dir/newname1.txt');
$zip->addFile('/path/to/newname.txt','dir/newname2.txt');
$zip->addFile('/path/to/newname.txt','dir/dir/newname3.txt');
$zip->addFile('/path/to/newname.txt','dir/dir/dir/newname4.txt');
for ($i=0; $i< $zip->numFiles;++$i) {
$aZipDtls = $zip->statIndex($i);
echo $aZipDtls['name'],"\n";
}
$zip->close();
?>
Should cover all questions. That will unzip with exactly the structure you'd expect it to. The discrepancy is likely due to the way WinRar displays the archive structure.

Categories