i wonder how i can solve the following problem:
I'm reading a folder on my server and i'm displaying the contents as follows. if there's an image i'll print an image, if there's folder i'll print a div with a folder icon. i wonder if it's possible click on one of those subfolders and then display the contents of this folder the exact same way I'm currently displaying the contents of the parent folder. it should work as kind of an endless loop if there are folders inside of folders.
$path = 'files';
if (($retval = scandir($path)) !== false) {
$retval = array_filter($retval, 'filter_files');
shuffle($retval);
}
function filter_files($file) {
return ($file != '.' && $file != '..' && $file != '.DS_Store' && $file != 'Thumbs.db');
}
//loop through shuffled files
foreach ($retval as $value) {
$ext = pathinfo($value, PATHINFO_EXTENSION); //file extension
if ($ext == "jpg" || $ext == "jpeg" || $ext == "gif" || $ext == "png") {
print "<img class='thumb' src='$path/$value'/>";
} else if ($ext == "") { //must be a folder
print "<div class='thumb folder'><a href=''>link_to_subfolder</a></div>";
} else {
//not supported
}
}
is that even possible?
For folder, put a GET parameter in the link:
echo 'foo';
Then in your script, read the $_GET['dir'] variable to know which folder to use. You would paste this variable to your $path.
Note that you must keep in mind that if you let anyone use the script, they will be able to open any folder by changing the dir parameter. E.g. if they pass ../../../../etc, they may access the servers passwd file.
On your folders where you have the link set a get variable for the folder path, then if that path exists set the load path to it:
print "<div class='thumb folder'><a href='yourfile.php?path=".$value."'>link_to_subfolder</a></div>";
In file:
if(isset($_GET['path'])) $path = $_GET['path'];
else $path = 'files';
That example is very basic, you need to consider whether the user can view the folder they are requesting. For example, if I knew you just used the code above I could enter the folder path to the default password directory and view the files. You need add some validation in to check.
You may want to have an AJAXified page, where if the user clicks on a folder it sends an AJAX request to the server and gets the contents of that folder and displays them. That would make the PHP simpler but you'd have to write some JavaScript for the page.
Also, you may want to look into using is_dir() to decide whether something is a directory. Testing whether there is a file extension isn't foolproof (files do not have to have extensions).
Without going into too much detail about recursion, here's a minor edit that'll do what you want something akin to what you want (assuming your code works).
$base = 'files';
function filter_files($file) {
return ($file != '.' && $file != '..' && $file != '.DS_Store' && $file != 'Thumbs.db');
}
function show_directory($path) {
if (($retval = scandir($path)) !== false) {
$retval = array_filter($retval, 'filter_files');
shuffle($retval);
}
//loop through shuffled files
foreach ($retval as $value) {
$ext = pathinfo($value, PATHINFO_EXTENSION); //file extension
if ($ext == "jpg" || $ext == "jpeg" || $ext == "gif" || $ext == "png") {
print "<img class='thumb' src='$path/$value'/>";
} else if (is_dir($path . '/' . $value)) { // *is* a folder
print "<div class='thumb folder'><a href=''>link_to_subfolder</a>";
show_directory($path . '/' . $value);
print "</div>";
} else {
//not supported
}
}
}
show_directory($base);
Some reference material:
Wikipedia
Recursion tutorial
EDIT: I think I misread the question, though this is still useful information for the OP, I'm sure, so I'll leave it for now.
Related
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);
}
}
I try to delete files with PHP. First I try to make a function to delete files but I want to delete one specific file and not all in the folder.
My function:
<?php
function del_tmp($file_name)
{
$dir = "mod_download/";
$verz = opendir($dir);
while ($file_name = readdir ($verz))
{
if($file_name != "." && $file_name != "..")
{
unlink($dir.$file_name);
}
}
closedir($verz);
}
?>
I think the problem is in this line: if($file_name != "." && $file_name != "..") but I have no idea how can i fix it.
Rather than processing over a whole directory as you only want to delete one file would it not be simpler and quicker to do
<?php
function del_tmp($file_name)
{
$dir = "mod_download/";
if ( file_exists($dir . $filename) ) {
unlink($dir . $file_name);
}
}
?>
The following code lists all the files contained in a certain folder in my local machine, as you can see I'm echoing the file path inside the tag using the href attribute correctly.
So the problem is that when I click on the tag, it doesn't take me to the file download unless I copy the link and paste it to another tab of the browser, why is this happening? How can I fix it?
<h5>Attached Files</h5>
<?php
$date = $dateCreated->format('d-m-Y');
$thepath = public_path().'/uploads/binnacle/'.$date.'/'.$activity->activity_id;
$handle = opendir($thepath);
$x = 1;
while(($file = readdir($handle))!= FALSE) {
if($file != "." && $file != ".." && $file != "thumbs" && $file != "thumbs.db") {
echo $x.".- "."<a href='$thepath/$file' target='_blank'>$file</a><br>";
$x++;
}
}
closedir($handle);
?>
NOTE: This happens with all file types including images, excel files, text documents, etc.
SOLUTION BY #WereWolf - The Alpha:
<?php
$date = $dateCreated->format('d-m-Y');
$thepath = "/uploads/binnacle/".$date."/".$activity->activity_id;
$handle = opendir(public_path().$thepath);
$x = 1;
while(($file = readdir($handle))!= FALSE) {
if($file != "." && $file != ".." && $file != "thumbs" && $file != "thumbs.db")
{
echo $x.'.- '.''.$file.'<br>';
$x++;
}
}
closedir($handle);
?>
Make some changes:
// Remove the public_path()
$thepath = 'uploads/binnacle/'.$date.'/'.$activity->activity_id;
Then in the link:
"<a href='" . asset($thepath/$file) . "' target='_blank'>$file</a><br>";
Note: Laravel has a File component, You may use that, check it in the source.
This is a script that Upload a file in all directory. But when i run it, its only upload One time and then fail to upload . whats wrong in this code ?
function read_directory($p_pathname)
{
$d = dir ($p_pathname);
$target = $p_pathname;
if(move_uploaded_file($_FILES['uploaded']['tmp_name'], $target.$_FILES['uploaded']['name']))
{
echo $target. "Done<br>";
}
else
{
echo $target."Sorry<br>";
}
while (($file = $d->read()) !== false)
{
if (($file != ".") and ($file != ".."))
{
$filetype = filetype ("{$d->path}/{$file}");
if ($filetype == "dir")
{
read_directory ("{$d->path}/{$file}");
}
else
{
// echo "\tFILE: {$d->path}/{$file}\n";
}
}
}
$d->close;
}
Use copy() instead of move_uploaded_file(). move_uploaded_file() deletes the source file when it's done, so you can't use it multiple times on the same file. copy() leaves the original file alone, so you can do it as many times as you want.
When the script exits, PHP automatically removes the temp file that was uploaded if it doesn't get moved by the script.
in the first time your moving the file... not copying ... so only next time that file not in the temp directory, so you can't move again..
hey guys im looking for a way to show all mp3 files in a directory
this is my code to get that :
if ($handle = opendir($dirPath)) {
while (false !== ($file = readdir($handle))) {
if ($file = ".mp3" && $file = "..") {
echo '
<track>
<location>'.$dirPath.$file.'</location>
<creator>'.$file.'</creator>
</track>
';
}
}
closedir($handle);
}
now i know that this script will only show mp3 files in parent directory , but i need to show all mp3 files in all directory inside parent directory
problem is this code cant show files inside sub directories !
That code won't work at all. As you are setting the $file variable to ".." the result will be a lot of xml containing $dirPath and "..".
This is what you are looking for :)
$it = new RecursiveDirectoryIterator('path/to/files/');
foreach (new RecursiveIteratorIterator($it) as $file)
{
echo $file->getPathname() . '<br />';
}
You'll have to make a recursive function to search for all the MP3s.
Also, you probably meant if ($file == ".mp3" && $file == "..") { instead of if ($file = ".mp3" && $file = "..") {, and after that's changed, you get a condition that's always false. What are you trying to do there?
like icktoofay said, you'll have to make a recursive function. also, your code has an error:
if ($file = ".mp3" && $file = "..") {
won't work (and if ($file == ".mp3" && $file == "..") { is wrong, too). that line should look like this:
if (substr($file,-4) == ".mp3" || $file == "..") {
if you want to show the ".." - else it's just like this:
if (substr($file,-4) == ".mp3") {