Renaming files in PHP? - php

I want the script to go into the folder 'images', take every file, cut the first four characters and rename it.
PHP
<?php
$path = './images/';
if ($handle = opendir($path))
{
while (false !== ($fileName = readdir($handle)))
{
if($fileName!=".." && $fileName!=".")
{
$newName = substr($fileName, 4);
$fileName = $path . $fileName;
$newName = $path . $newName;
rename($fileName, $newName);
}
}
closedir($handle);
}
?>
This is how the files in the images folder are named:
0,78test-1.jpg
0,32test-2.jpg
0,43test-3.jpg
0,99test-4.jpg
and this is what i want them to look like:
test-1.jpg
test-2.jpg
test-3.jpg
test-4.jpg
The problem is the script cuts out the first 8, 12 or 16 characters, not four as i want it! So when i execute it my files look like this:
-1.jpg
-2.jpg
-3.jpg
-4.jpg
UPDATE
I also tracked the packages to make sure i am not executing the script multiple times. The script is only executed once!

A slightly different approach though essentially the same with the substr part this worked fine for tests on local system.
$dir='c:/temp2/tmpimgs/';
$files=glob( $dir . '*.*' );
$files=preg_grep( '#(\.jpg$|\.jpeg$|\.png$)#i', $files );
foreach( $files as $filename ){
try{
$path=pathinfo( $filename, PATHINFO_DIRNAME );
$name=pathinfo( $filename, PATHINFO_BASENAME );
$newname=$path . DIRECTORY_SEPARATOR . substr( $name, 4, strlen( $name ) );
if( strlen( $filename ) > 4 ) rename( $filename, $newname );
} catch( Exception $e ){
echo $e->getTraceAsString();
}
}

You may want to try this little Function. It would do just the proper renaming for you:
<?php
$path = './images/';
function renameFilesInDir($dir){
$files = scandir($dir);
// LOOP THROUGH THE FILES AND RENAME THEM
// APPROPRIATELY...
foreach($files as $key=>$file){
$fileName = $dir . DIRECTORY_SEPARATOR . $file;
if(is_file($fileName) && !preg_match("#^\.#", $file)){
$newFileName = preg_replace("#\d{1,},\d{1,}#", "", $fileName);
rename($fileName, $newFileName);
}
}
}
renameFilesInDir($path);

<?php
$path = './images/';
if ($handle = opendir($path))
{
while (false !== ($fileName = readdir($handle)))
{
if($fileName!=".." && $fileName!=".")
{
//change below line and find first occurence of '-' and then replace everything before this with 'test' or any keyword
$newName = substr($fileName, 4);
$fileName = $path . $fileName;
$newName = $path . $newName;
rename($fileName, $newName);
}
}
closedir($handle);
}
?>

Related

Php copy : Invalid argument error only on inside while loop and working for last record

Reading the file for the image url and calling the copy function.
imagecopy.txt
https://server.com/2017/12/check.png
https://server.com/2017/12/contacts.png
https://server.com/2018/06/CDP.bmp
https://server.com/module-acculturation-1.png
While copying the files from the url, getting the failed to open stream: Invalid argument error only on inside while loop. but works for the last record if the file has more files.
<?php
$file=fopen("imagecopy.txt","r") or exit("Unable to open file!");
while (!feof($file))
{
$source = fgets($file);
$imagename = explode("/", $source);
$pathname = 'uploads/' . date("Y") . '/' . date("m") . '/';
if (!is_dir($pathname))
{
mkdir($pathname, 0777, true);
}
$destination = $pathname.end($imagename);
copyimageURL($source, $destination);
}
fclose($file);
function copyimageURL($source, $destination)
{
echo $source;
echo "<br>";
echo $destination;
copy($source, $destination);
}
?>
1.Working fine with singe record
2.Copying the last image only if the file has more images list.
I'm guessing imagecopy.txt you're reading ends in a newline, which makes the last line of the file blank.
If you change
$source = fgets($file);
to
$source = trim(fgets($file));
if( empty($source) ) continue;
it should work fine
Try this:
if ($file) {
while (($name = fgets($file)) !== false) {
$imagename = basename($name);
$pathname = 'uploads/' . date("Y") . '/' . date("m") . '/';
if (!is_dir($pathname))
mkdir($pathname, 0777, true);
$destination = $pathname.$imagename;
copyimageURL(trim($name), $destination);
}
fclose($file);
}

Copy all files from one folder to another Folder using PHP scripts?

Basically, my requirement is, I want to move all files from one folder to another folder using PHP scripts. Any one can help me. I am trying this, but I am getting error
$mydir = dirname( __FILE__ )."/html/images/";
if(!is_dir($mydir)){
mkdir("html/images");
}
// Move all images files
$files = glob("images/*.");
foreach($files as $file){
$file_to_go = str_replace("images/","html/images/",$file);
copy($file, $file_to_go);
}
// images folder creation using php
$mydir = dirname( __FILE__ )."/html/images";
if(!is_dir($mydir)){
mkdir("html/images");
}
// Move all images files
$files = glob("images/*.*");
foreach($files as $file){
$file_to_go = str_replace("images/","html/images/",$file);
copy($file, $file_to_go);
}
Try this :
<?php
$src = 'pictures';
$dst = 'dest';
$files = glob("pictures/*.*");
foreach($files as $file){
$file_to_go = str_replace($src,$dst,$file);
copy($file, $file_to_go);
}
?>
foreach(glob('old_directory/*.*') as $file) {
copy('old_directory/'.$file, 'new_directory/'.$file);
}
Use array_map:
// images folder creation using php
function copyFile($file) {
$file_to_go = str_replace("images/","html/images/",$file);
copy($file, $file_to_go);
}
$mydir = dirname( __FILE__ )."/html/images";
if(!is_dir($mydir)){
mkdir("html/images");
}
// Move all images files
$files = glob("images/*.*");
print_r(array_map("copyFile",$files));
This One Works for me...........
Thanks to this man
http://www.codingforums.com/php/146554-copy-one-folder-into-another-folder-using-php.html
<?php
copydir("admin","filescreate");
echo "done";
function copydir($source,$destination)
{
if(!is_dir($destination)){
$oldumask = umask(0);
mkdir($destination, 01777); // so you get the sticky bit set
umask($oldumask);
}
$dir_handle = #opendir($source) or die("Unable to open");
while ($file = readdir($dir_handle))
{
if($file!="." && $file!=".." && !is_dir("$source/$file"))
copy("$source/$file","$destination/$file");
}
closedir($dir_handle);
}
?>
This should work just fine:
// Get array of all source files
$files = scandir("source");
// Identify directories
$source = "source/";
$destination = "destination/";
// Cycle through all source files
foreach ($files as $file) {
if (in_array($file, array(".",".."))) continue;
// If we copied this successfully, mark it for deletion
if (copy($source.$file, $destination.$file))
{
$delete[] = $source.$file;
}
}
// Delete all successfully-copied files
foreach ($delete as $file)
{
unlink($file);
}
or with rename() and some error checking:
$srcDir = 'dir1';
$destDir = 'dir2';
if (file_exists($destDir)){
if (is_dir($destDir)) {
if (is_writable($destDir)) {
if ($handle = opendir($srcDir)) {
while (false !== ($file = readdir($handle))) {
if (is_file($srcDir . '/' . $file)) {
rename($srcDir . '/' . $file, $destDir . '/' . $file);
}
}
closedir($handle);
} else {
echo "$srcDir could not be opened.\n";
}
} else {
echo "$destDir is not writable!\n";
}
} else {
echo "$destDir is not a directory!\n";
}
} else {
echo "$destDir does not exist\n";
}
You can use this recursice function.
<?php
function copy_directory($source,$destination) {
$directory = opendir($source);
#mkdir($destination);
while(false !== ( $file = readdir($directory)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($source . '/' . $file) ) {
copy_directory($source . '/' . $file,$destination . '/' . $file);
}
else {
copy($source . '/' . $file,$destination . '/' . $file);
}
}
}
closedir($directory);
}
?>
Referrence : http://php.net/manual/en/function.copy.php
I had a similar situation where I needed to copy from one domain to another, I solved it using a tiny adjustment to the "very easy answer" given by "coDe murDerer" above:
Here is exactly what worked in my case, you can as well adjust to suit yours:
foreach(glob('../folder/*.php') as $file) {
$adjust = substr($file,3);
copy($file, '/home/user/abcde.com/'.$adjust);
Notice the use of "substr()", without it, the destination becomes '/home/user/abcde.com/../folder/', which might be something you don't want.
So, I used substr() to eliminate the first 3 characters(../) in order to get the desired destination which is '/home/user/abcde.com/folder/'. So, you can adjust the substr() function and also the glob() function until it fits your personal needs. Hope this helps.

Bulk update in php using some conditions for filename

I have a folder and have multiple files over there. The file has the below pattern for example.
The file names should be renamed from
file1.mp4.png
file2.flv.png
file3.xxx.png (xxx - can be anything)
to as follows (the last extension remains).
file1.png
file2.png
file3.png
Files having non-png extension should be left untouched.
I am using the logic mentioned in Bulk Rename Files in a Folder - PHP
$handle = opendir("path to directory");
if ($handle) {
while (false !== ($fileName = readdir($handle))) {
$newName = (how to get new filename) // I am struck here
rename($fileName, $newName);
}
closedir($handle);
}
How best I can do this to do a bulk update?
<?php
// Select all PNG Files
$matches = glob("*.[pP][nN][gG]");
// check if we found any results
if ( is_array ( $matches ) ) {
// loop through all files
foreach ( $matches as $filename) {
// rename your files here
$newfilename = current(explode(".", $filename)).".png";
rename($filename, $newfilename);
echo "$filename -> $newfilename";
}
}
?>
try this
$handle = opendir("path to directory");
if ($handle) {
while (false !== ($fileName = readdir($handle))) {
$arr_names = explode(".", $fileName);
$size = sizeof($arr_names);
$ext = $arr_names[$size-1];
if($fileName=="." || $fileName==".." || is_dir($fileName))
{
continue; // skip png
}
if($ext=='png' || $ext=='PNG')
{
$newName = $arr_names[0].".".$ext;
rename($fileName, $newName);
}
}
closedir($handle);
}
Shortest using regex
$handle = opendir("path to directory");
if ($handle) {
while (false !== ($fileName = readdir($handle))) {
$newName = preg_replace("/\.(.*?)\.png$/", '', $fileName); // removes .xxx.png
rename($fileName, ($newName . '.png')); // renames file1.png
}
closedir($handle);
}

Creating a ZIP backup file - No errors thrown, but the ZIP file is not showing up

$path = '/home/username/www/;
if($zip = new ZipArchive){
if($zip->open('backup_'. time() .'.zip', ZipArchive::CREATE)){
if(false !== ($dir = opendir($path))){
while (false !== ($file = readdir($dir))){
if ($file != '.' && $file != '..' && $file != 'aaa'){
$zip->addFile($path . $file);
echo 'Adding '. $file .' to path '. $path . $file .' <br>';
}
}
}
else
{
echo 'Can not read dir';
}
$zip->close();
}
else
{
echo 'Could not create backup file';
}
}
else
{
echo 'Could not launch the ZIP libary. Did you install it?';
}
Hello again Stackoverflow! I want to backup a folder with all its content including (empty) subfolders and every file in them, whilst excluding a single folder (and ofcourse . and ..). The folder that needs to be excluded is aaa.
So when I run this script (every folder does have chmod 0777) it runs without errors, but the ZIP file doesn't show up. Why? And how can I solve this?
Thanks in advance!
have you tried to access the zip folder via PHP rather than looking in FTP as to whether it exists or not - as it might not appear immediately to view in FTP
function addFolderToZip($dir, $zipArchive, $zipdir = ''){
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
//Add the directory
if(!empty($zipdir)) $zipArchive->addEmptyDir($zipdir);
// 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, and any other directories you want
if( ($file !== ".") && ($file !== "..") && ($file !== "aa")){
addFolderToZip($dir . $file . "/", $zipArchive, $zipdir . $file . "/");
}
}else{
// Add the files
$zipArchive->addFile($dir . $file, $zipdir . $file);
}
}
}
}
}
After a while of fooling around this is what I found working. Use it as seen below.
$zipArchive = new ZipArchive;
$name = 'backups\backup_'. time() .'.zip';
$zipArchive->open($name, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE);
addFolderToZip($path, $zipArchive);
Here's my answer, checks if the modification time is greater then something as well.
<?php
$zip = new ZipArchive;
$zip_name = md5("backup".time()).".zip";
$res = $zip->open($zip_name, ZipArchive::CREATE);
$realpath = str_replace('filelist.php','',__FILE__);
$path = realpath('.');
$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
foreach($objects as $name => $object){
if (is_file($object)) {
$file_count ++;
$epoch = $object->getMTime();
if($epoch>='1374809360'){ // Whatever date you want to start at
$array[] = str_replace($realpath,'',$object->getPathname());
}
}
}
foreach($array as $files) {
$zip->addFile($files);
}
$zip->close();
echo $zip_name.'-'.$file_count.'-'.$count_files;
?>

PHP: How to list files in a directory without listing subdirectories

This is the starting portion of my code to list files in a directory:
$files = scandir($dir);
$array = array();
foreach($files as $file)
{
if($file != '.' && $file != '..' && !is_dir($file)){
....
I'm trying to list all files in a directory without listing subfolders. The code is working, but showing both files and folders. I added !is_dir($file) as you see in my code above, but the results are still the same.
It should be like this, I think:
$files = scandir($dir);
foreach($files as $file)
{
if(is_file($dir.$file)){
....
Just use is_file.
Example:
foreach($files as $file)
{
if( is_file($file) )
{
// Something
}
}
This will scan the files then check if . or .. is in an array. Then push the files excluding . and .. in the new files[] array.
Try this:
$scannedFiles = scandir($fullPath);
$files = [];
foreach ($scannedFiles as $file) {
if (!in_array(trim($file), ['.', '..'])) {
$files[] = $file;
}
}
What a pain for something so seemingly simple! Nothing worked for me...
To get a result I assumed the file name had an extension which it must in my case.
if ($handle = opendir($opendir)) {
while (false !== ($entry = readdir($handle))) {
$pos = strpos( $entry, '.' );
if ($entry != "." && $entry != ".." && is_numeric($pos) ) {
............ good entry
Use the DIRECTORY_SEPARATOR constant to append the file to its directory path too.
function getFileNames($directoryPath) {
$fileNames = [];
$contents = scandir($directoryPath);
foreach($contents as $content) {
if(is_file($directoryPath . DIRECTORY_SEPARATOR . $content)) {
array_push($fileNames, $content);
}
}
return $fileNames;
}
This is a quick and simple one liner to list ONLY files. Since the user wants to list only files, there is no need to scan the directory and return all the contents and exclude the directories. Just get the files of any type or specific type. Use * to return all files regardless of extension or get files with a specific extension by replacing the * with the extension.
Get all files regardless of extension:
$files = glob($dir . DIRECTORY_SEPARATOR . "*");
Get all files with the php extension:
$files = glob($dir . DIRECTORY_SEPARATOR . "*.php");
Get all files with the js extension:
$files = glob($dir . DIRECTORY_SEPARATOR . "*.js");
I use the following for my sites:
function fileList(string $directory, string $extension="") :array
{
$filetype = '*';
if(!empty($extension) && mb_substr($extension, 0, 1, "UTF-8") != '.'):
$filetype .= '.' . $extension;
else:
$filetype .= $extension;
endif;
return glob($directory . DIRECTORY_SEPARATOR . $filetype);
}
Usage :
$files = fileList($configData->includesDirectory, '');
With my custom function, I can include an extension or leave it empty. Additionally, I can forget to place the . before the extension and it will succeed.

Categories