It seems
chmod("*.txt", 0660);
doesn't work.
I know I can:
chmod the files one by one: it works but I do not know all the names in advance, so I cannot use it.
Use exec. It works but I don't like it for several reasons (speed, security, and so on).
Use scandir. It works but again, slow and I guess too much for a simple operation
I really want to use chmod directly. Is it even possible? Thank you.
So you can do this using scandir like you mentioned and yes filesystem can be pretty slow, you can add a check in so you do not do it to files you have already processed
<?php
$files = scandir('./');
foreach ($files as $file) {
// check here so you don't have to do every file again
if (substr(sprintf('%o', fileperms($file)), -4) === "0660") {
echo "skipping " . $file;
continue;
}
$extension = pathinfo($file)['extension'];
if ($extension === 'txt') {
chmod($file, 0660);
}
}
Or you could use glob
<?php
$files = glob('./*.{txt}', GLOB_BRACE);
foreach($files as $file) {
// check here so you don't have to do every file again
if (substr(sprintf('%o', fileperms($file)), -4) === "0660") {
echo "skipping " . $file;
continue;
}
$extension = pathinfo($file)['extension'];
if ($extension === 'txt') {
chmod($file, 0660);
}
}
Related
I am trying for the life of me to find the best way to delete all files in a single directory excluding a single file extension, ie anything that is not .zip
The current method I have used so far which successfully deletes all files is:
$files = glob('./output/*');
foreach($files as $file)
{
if(is_file($file))
unlink($file); // delete file
}
I have tried modifying this like so:
$files = glob('./output/**.{!zip}', GLOB_BRACE);
foreach($files as $file)
{
if(is_file($file))
unlink($file); // delete file
}
However, I am not hitting the desired result. I have changed the line as follows which has deleted only the zip file itself (so I can do the opposite of desired).
$files = glob('./output/*.{zip}', GLOB_BRACE);
I understand that there are other methods to read directory contents and use strpos/preg_match etc to delete accordingly. I have also seen many other methods, but these seem to be quite long winded or intended for recursive directory loops.
I am certainly not married to glob(), I would simply like to know the simplest/most efficient way to delete all files in a single directory that are not a .zip file.
Any help/advice is appreciated.
$exclude = array("zip");
$files = glob("output/*");
foreach($files as $file) {
$extension = pathinfo($file, PATHINFO_EXTENSION);
if(!in_array($extension, $exclude)) unlink($file);
}
This code works by having an array of excluded extensions, it loads up all files in a directory then checks for the extension of each file. If the extension is in the exclusion list then it doesn't get deleted. Else, it does.
This should work for you:
(I just use array_diff() to get all files which are different to *.zip and then i go through these files and unlink them)
<?php
$files = array_diff(glob("*.*"), glob("*.zip"));
foreach($files as $file) {
if(is_file($file))
unlink($file); // delete file
}
?>
How about calling to the shell? So in Linux:
$path = '/path/to/dir/';
$shell_command = escapeshellcmd('find ' . $path .' ! -name "*.zip" -exec rm -r {}');
$output = shell_exec($shell_command);
I would simply like to know the simplest/most efficient way to delete all files in a single directory that are not a .zip file.
SPL Iterators are very effective and efficient.
This is what I would use:
$folder = __DIR__;
$it = new FilesystemIterator($folder, FilesystemIterator::SKIP_DOTS);
foreach ($it as $file) {
if ($file->getExtension() !== 'zip') {
unlink($file->getFilename());
}
}
Have you tried this:
$path = "dir/";
$dir = dir($path);
while ($file = $dir->read()) {
if ($file != "." && $file != ".." && substr($file, -4) !== '.zip') {
unlink($file);
}
}
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!
I have a directory with a lot of files inside:
pic_1_79879879879879879.jpg
pic_1_89798798789798789.jpg
pic_1_45646545646545646.jpg
pic_2_12345678213145646.jpg
pic_3_78974565646465645.jpg
etc...
I need to list only the pic_1_ files. Any idea how I can do?
Thanks in advance.
Use the glob() function
foreach (glob("directory/pic_1_*") as $filename) {
echo "$filename";
}
Just change directory in the glob call to the proper path.
This does it all in one shot versus grabbing the list of files and then filtering them.
The opend dir function will help you
$dir ="your path here";
$filetoread ="pic_1_";
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
if (strpos($file,$filetoread) !== false)
echo "filename: $file : filetype: " . filetype($dir . $file) . "\n";
}
closedir($dh);
}
}
good luck see php.net opendir
This is what glob() is for:
glob — Find pathnames matching a pattern
Example:
foreach (glob("pic_1*.jpg") as $file)
{
echo $file;
}
Use scandir to list all the files in a directory and then use preg_grep to get the list of files which match the pattern you are looking for.
This is one of the samples from the manual
http://nz.php.net/manual/en/function.readdir.php
<?php
if ($handle = opendir('.')) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
echo "$file\n";
}
}
closedir($handle);
}
?>
you can modify that code to test the filename to see if it starts with pic_1_
using something like this
if (substr($file, 0, 6) == 'pic_1_')
Manual reference for substr
http://nz.php.net/manual/en/function.substr.php
I am trying to read a file name current.conf and then use the name of a folder saved in it to opendir(); when I open:
$file = fopen("current.conf","r");
$lines = fread($file,"10");
fclose($file);
$lines = "/".$lines."/";
echo $lines;
$dir=opendir($lines);
$files=array();
while (($file=readdir($dir)) !== false)
{
if ($file != "." and $file != ".." and $file != "index.php")
{
array_push($files, $file);
}
}
closedir($dir);
The current.conf has only one line in it:
2.1-2328
I am not able to open the folder that is named in the conf files. I have a feeling it has to do with the formatting of the conf file but not sure.
I suspect the directory doesn't exist (or you don't have the rights to read it), but without a specific error (opendir is most likely throwing an E_WARNING - check your logs, etc.)
Incidentally, you could re-write your code to reduce its complexity as follows:
<?php
// Grab the contents of the "current.conf" file, removing any linebreaks.
$dirPath = '/'.trim(file_get_contents('current.conf')).'/';
$fileList = scandir($dirPath);
if(is_array($fileList)) {
foreach($fileList as $file) {
// Skip the '.' and '..' in here as required.
echo $file."\n";
}
}
else echo $dirPath.' cound not be scanned.';
?>
In this instance the call to scandir will throw an E_WARNING.
How to get the file names inside a directory using PHP?
I couldn't find the relevant command using Google, so I hope that this question will help those who are asking along the similar lines.
There's a lot of ways. The older way is scandir but DirectoryIterator is probably the best way.
There's also readdir (to be used with opendir) and glob.
Here are some examples on how to use each one to print all the files in the current directory:
DirectoryIterator usage: (recommended)
foreach (new DirectoryIterator('.') as $file) {
if($file->isDot()) continue;
print $file->getFilename() . '<br>';
}
scandir usage:
$files = scandir('.');
foreach($files as $file) {
if($file == '.' || $file == '..') continue;
print $file . '<br>';
}
opendir and readdir usage:
if ($handle = opendir('.')) {
while (false !== ($file = readdir($handle))) {
if($file == '.' || $file == '..') continue;
print $file . '<br>';
}
closedir($handle);
}
glob usage:
foreach (glob("*") as $file) {
if($file == '.' || $file == '..') continue;
print $file . '<br>';
}
As mentioned in the comments, glob is nice because the asterisk I used there can actually be used to do matches on the files, so glob('*.txt') would get you all the text files in the folder and glob('image_*') would get you all files that start with image_
The Paolo Bergantino's answer was fine but is now outdated!
Please consider the below official ways to get the Files inside a directory.
FilesystemIterator
FilesystemIterator has many new features compared to its ancestor DirectoryIterator as for instance the possibility to avoid the statement if($file->isDot()) continue;. See also the question Difference between DirectoryIterator and FilesystemIterator.
$it = new FilesystemIterator(__DIR__);
foreach ($it as $fileinfo) {
echo $fileinfo->getFilename() , PHP_EOL;
}
RecursiveDirectoryIterator
This snippet lists PHP files in all sub-directories.
$dir = new RecursiveDirectoryIterator(__DIR__);
$flat = new RecursiveIteratorIterator($dir);
$files = new RegexIterator($flat, '/\.php$/i');
foreach($files as $file) {
echo $file , PHP_EOL;
}
See also the Wrikken's answer.
Most of the time I imagine you want to skip . and ... Here is that with
recursion:
<?php
$o_dir = new RecursiveDirectoryIterator('.', FilesystemIterator::SKIP_DOTS);
$o_iter = new RecursiveIteratorIterator($o_dir);
foreach ($o_iter as $o_name) {
echo $o_name->getFilename();
}
https://php.net/class.recursivedirectoryiterator
The old way would be:
<?php
$path = realpath('.'); // put in your path here
$dir_handle = #opendir($path) or die("Unable to open $path");
$directories = array();
while ($file = readdir($dir_handle))
$directories[] = $file;
closedir($dir_handle);
?>
As already mentioned the directory iterator might be the better way for PHP 5.