I need to get the contents of several files within a directory but which is the best way of doing this?
I am using
$data = file_get_contents('./files/myfile.txt');
but I want every file without having to specify the file individually as above.
You can use glob to get particular file extention and file_get_contents to get the content
$content = implode(array_map(function ($v) {
return file_get_contents($v);
}, glob(__DIR__ . "/files/*.txt")));
/**
* Change the path to your folder.
* This must be the full path from the root of your
* web space. If you're not sure what it is, ask your host.
*
* Name this file index.php and place in the directory.
*/
// Define the full path to your folder from root
$path = "/home/content/s/h/a/shaileshr21/html/download";
// Open the folder
$dir_handle = #opendir($path) or die("Unable to open $path");
// Loop through the files
while ($file = readdir($dir_handle)) {
$data = file_get_contents('$filet');
}
// Close
closedir($dir_handle);
You can dir the directory and loop through it to get the contents of all files.
<?php
$path = './files';
$d = dir($path);
$contents = '';
while (false !== ($entry = $d->read())) {
if (!($entry == '..' || $entry == '.')) {
$contents .= file_get_contents($path.'/'.$entry);
}
}
$d->close();
?>
If you only want .txt files you can change the if statement of the code above from:
if (!($entry == '..' || $entry == '.')) {
to:
if (substr($entry, -4) == '.txt') {
This will result to a variable $contents that is type string and has all the contents of all the files (or only txt files if you select the 2nd solution) that are in the ./files dir.
Related
I want to delete files in a specific directory in PHP. How can I achieve this?
I have the following code but it does not delete the files.
$files = array();
$dir = dir('files');
while ($file = $dir->read()) {
if ($file != '.' && $file != '..') {
$files[] = $file;
}
unlink($file);
}
I think your question isn't specific, this code must clear all files in the directory 'files'.
But there are some errors in that code I think, and here is the right code:
$files= array();
$dir = dir('files');
while (($file = $dir->read()) !== false) { // You must supply a condition to avoid infinite looping
if ($file != '.' && $file != '..') {
$files[] = $file; // In this array you push the valid files in the provided directory, which are not (. , ..)
}
unlink('files/'.$file); // This must remove the file in the queue
}
And finally make sure that you provided the right path to dir().
You can get all directory contents with glob and check if the value is a file with is_file() before unlinking it.
$files = glob('files/*'); // get directory contents
foreach ($files as $file) { // iterate files
// Check if file
if (is_file($file)) {
unlink($file); // delete file
}
}
If you want to remove files matching a pattern like .png or .jpg, you have to use
$files = glob('/tmp/*.{png,jpg}', GLOB_BRACE);
See manual for glob.
I have this script that gets the first file name from a directory, with this variable deletes a line from a file (register file) and then deletes the actual file from the directory, the thing is that I need this action to take place only if there are files in the directory and in case of more than one file the action continues taking place with the second, third files, and so on until the directory is empty... how? help please....
// Register file
$registerf = "results/register.php";
// Get the firs file name
$firstFile = scandir("results/todel/")[2];
// Delete it from register file
$regex = "'/$firstFile/d'";
$cmd = "sed -i $regex $registerf";
shell_exec($cmd);
// Actually delete the file from directory
unlink("results/todel/".$firstFile);
// Register file
$registerf = "results/register.php";
//go through each file in dir
foreach(scandir("results/todel/") as $file){
if ($file != "." && $file != ".."){
// Delete it from register file
$regex = "'/$file/d'";
$cmd = "sed -i $regex $registerf";
shell_exec($cmd);
// Actually delete the file from directory if it's a file
unlink("results/todel/".$file);
}
}
if ($handle = opendir('/mydir/')) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
unlink("/mydir/".$file);
}
}
closedir($handle);
}
Hope this may helps you
I'm writing a simple upload/download page in PHP. With the following code I can see files being the content of folder above the root but it's impossible to access those files. What could be the reason?
$targetdir="/../cat/";
if ($dir = #opendir($targetdir))
{
while ($file = readdir($dir))
{
if ($file != "." && $file != "..")
echo "<td>".$file."</td>";
}
closedir($dir);
}
You cannot access files above the web root directory, instead you will need to write a script to do this for you.
downloadfile.php?file=somefile.txt
<?php
$file = $_GET['file'];
if (strpos($file, '..') !== false) {
throw new \Exception('Illegal path requested');
}
/**
* this will restrict files to this directory or above as
* to not allow reading of files which you do not want a user to access
*/
$basePath = __DIR __ . '/../cat';
$fullPath = sprintf('%s/%s', $basePath, $file);
/** check to see if the file exists and is readable **/
if (false === is_readable($fullPath)) {
throw \Exception('file does not exist or is not accessible');
}
echo file_get_contents($file);
exit;
You must be very cautious when doing this, as you could allow someone to access files you don't want them to, including your source code, so make sure you're sanitizing the input.
As well you should change $target dir to the following, as it stands you're trying to go to the absolute root of the file system instead relative to the file which started the execution.
/** relative to the file that started the execution **/
$targetdir = "../cat/"
/** relative to the file that contains this variable declaration**/
$target = __DIR__ . "/../cat/"
I need to read only pdf files in a directory and then read the filename of every files then I will use the filename to rename some txt files. I have tried using only eregi function. but it seems cannot read all I need. how to read them well?
here's my code :
$savePath ='D:/dir/';
$dir = opendir($savePath);
$filename = array();
while ($filename = readdir($dir)) {
if (eregi("\.pdf",$filename)){
$read = strtok ($filename,"."); //get the filenames
//to rename some txt files using the filenames that I get before
//$testfile is text files that I've read before
$testfile = "$read.txt";
$file = fopen($testfile,"r") or die ('cannot open file');
if (filesize($testfile)==0){}
else{
$text = fread($file,55024);
fclose($file);
echo "</br>"; echo "</br>";
}
}
More elegant:
foreach (glob("D:/dir/*.pdf") as $filename) {
// do something with $filename
}
To get the filename only:
foreach (glob("D:/dir/*.pdf") as $filename) {
$filename = basename($filename);
// do something with $filename
}
You can do this by filter file type.. following is sample code.
<?php
// directory path can be either absolute or relative
$dirPath = '.';
// open the specified directory and check if it's opened successfully
if ($handle = opendir($dirPath)) {
// keep reading the directory entries 'til the end
$i=0;
while (false !== ($file = readdir($handle))) {
$i++;
// just skip the reference to current and parent directory
if (eregi("\.jpg",$file) || eregi("\.gif",$file) || eregi("\.png",$file)){
if (is_dir("$dirPath/$file")) {
// found a directory, do something with it?
echo " [$file]<br>";
} else {
// found an ordinary file
echo $i."- $file<br>";
}
}
}
// ALWAYS remember to close what you opened
closedir($handle);
}
?>
Above is demonstrating for file type related to images you can do the same for .PDF files.
Better explained here
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