Root
First_Folder
First_Folder_Pages
First_Folder_JS(js script here for ajax)
First_Folder_DB(php script that is linked from ajax request)
Second_Folder
Second_Folder_Pages
Second_Folder_JS(js script here for ajax)
Second_Folder_DB(php script that is linked from ajax request)
How can I get the direct path on the folder with names containing Pages using jQuery or PHP
Expected Output is like: ../../First_Folder/First_Folder_Pages or ../../Second_Folder/Second_Folder_Pages
This function w'd be enough for file list. Just make an ajax call to it, json_encode to output before send back to javascript
function scan($dir)
{
$output = array();
$handle = opendir($dir);
if ($handle != false) {
while ($file = readdir($handle)) {
if ($file == '.' || $file == '..')
continue;
$path = $dir . '/' . $file;
if (is_dir($path))
$output += scan($path);
else
$output[] = $path;
}
}
return $output;
}
İf you want to add folders to array too, just change the if statement like;
if (is_dir($path))
$output += scan($path);
$output[] = $path;
Also you can use RecursiveDirectoryIterator class too: stackoverflow
UPDATE
Just erase the "else" keyword if you want to add folders too in output.
If you call function like;
scan('/root/');
The output will give you results like;
'/root/First_Folder/First_Folder_file1',
'/root/Second_Folder/Second_Folder_file1',
'/root/Second_Folder/Second_Folder_file2'
But if u erase "else" keyword, you will get results like;
'/root/First_Folder',
'/root/First_Folder/First_Folder_file1',
'/root/Second_Folder',
'/root/Second_Folder/Second_Folder_file1',
'/root/Second_Folder/Second_Folder_file2'
Related
I have code that reads the images directory for a user (user 38 below) and returns an array of the file names, skipping the . and .. references.
// $dir = 38/images
$dirHandle = opendir($dir)$dirHandle = opendir($dir)
while (false !== ($fileName = readdir($dirHandle))) {
if ($fileName == "." || $fileName == "..")
continue;
-- Put file on array which gets returned to ajax load call at end --
}
This works fine but it seems to generate the access errors shown below:
Am I doing something fundamentally wrong?
Thanks
Unless you have an index.php file in your 38 and 38/images folders, you are issuing a get over a folder, over which you don't have permissions enough.
Check your script path, and your JS code in order to fix it.
I got to the bottom of this. It happens when a directory of images is being prefetched to the page:
while($fileName = readdir($dirHandle)) {
$filepath = $dir . $fileName;
echo ("<img class='galleryThumb' src='$filepath' >");
}
The trouble occurs when $fileName is "." or "..". The <img class='galleryThumb' src='$filepath' > echoed down with Ajax then has trouble evaluating a src attribute that's a directory rather than a file. I fixed it by adding a check for "." and ".." :
while($fileName = readdir($dirHandle)) {
if ($fileName == "." || $fileName == "..") {
continue;
}
$filepath = $dir . $fileName;
echo ("<img class='galleryThumb' src='$filepath' >");
}
Since you see 403 errors from network panel of javascript debugger, it is javascript, who is accesing these paths. The php code you posted has almost nothing to do with that.
I have a directory with 1.3 Million files that I need to move into a database. I just need to grab a single filename from the directory WITHOUT scanning the whole directory. It does not matter which file I grab as I will delete it when I am done with it and then move on to the next. Is this possible? All the examples I can find seem to scan the whole directory listing into an array. I only need to grab one at a time for processing... not 1.3 Million every time.
This should do it:
<?php
$h = opendir('./'); //Open the current directory
while (false !== ($entry = readdir($h))) {
if($entry != '.' && $entry != '..') { //Skips over . and ..
echo $entry; //Do whatever you need to do with the file
break; //Exit the loop so no more files are read
}
}
?>
readdir
Returns the name of the next entry in the directory. The entries are returned in the order in which they are stored by the filesystem.
Just obtain the directories iterator and look for the first entry that is a file:
foreach(new DirectoryIterator('.') as $file)
{
if ($file->isFile()) {
echo $file, "\n";
break;
}
}
This also ensures that your code is executed on some other file-system behaviour than the one you expect.
See DirectoryIterator and SplFileInfo.
readdir will do the trick. Check the exampl on that page but instead of doing the readdir call in the loop, just do it once. You'll get the first file in the directory.
Note: you might get ".", "..", and other similar responses depending on the server, so you might want to at least loop until you get a valid file.
do you want return first directory OR first file? both? use this:
create function "pickfirst" with 2 argument (address and mode dir or file?)
function pickfirst($address,$file) { // $file=false >> pick first dir , $file=true >> pick first file
$h = opendir($address);
while (false !== ($entry = readdir($h))) {
if($entry != '.' && $entry != '..' && ( ($file==false && !is_file($address.$entry)) || ($file==true && is_file($address.$entry)) ) )
{ return $entry; break; }
} // end while
} // end function
if you want pick first directory in your address set $file to false and if you want pick first file in your address set $file to true.
good luck :)
I have the following which is fairly slow. How can I speed it up?
(it scans a directory and makes headers out of the foldernames and retrieves the pdf files from within and adds them to lists)
$directories= array_diff(scandir("../pdfArchive/subfolder", 0), array('..', '.'));
foreach ($directories as $v) {
echo "<h3>".$v."</h3>";
$current = array_diff(scandir("../pdfArchive/subfolder/".$v, 0), array('..', '.'));
echo "<ul style=\"list-style-image: url(/images/pdf.gif); margin-left: 20px;\">";
foreach ($current as $vone) {
echo "<li><a target=\"blank\" href=\"../pdfArchive/subfolder/".$vone."\">".str_replace(".pdf", "", $vone)."</a>";
echo "</li><br>";
}
echo "</ul>";
}
Don't use array_diff() to filter out current and parent directory, use something like DirectoryIterator or glob() and then test whether it's . or .. via an if statement
glob() has a flag that allows you to retrieve only directories for your loops
Profile your code to see exactly what lines/functions are executing slowly
I'm not sure how fast array_diff() is when the array is very large, isn't it faster to simply add a separate check and make sure that '.' and '..' is not the returned name?
Other than that, I can't see there being anything really wrong.
What did you test to consider the current approach slow?
Here is a snippet of code I use that I adapted from php.net. It is very basic and goes through a given directory and lists the files contained within.
// The # suppresses any errors, $dir is the directory path
if (($handle = #opendir($dir)) != FALSE) {
// Loop over directory contents
while (($file = readdir($handle)) !== FALSE) {
// We don't want the current directory (.) or parent (..)
if ($file != "." && $file != "..") {
var_dump($file);
if (!is_dir($dir . $file)) {
// $file is really a file
} else {
// $file is a directory
}
}
}
closedir($handle);
} else {
// Deal with it
}
You may adapt this further to recurse over subdirectories by using is_dir to identify folders as I have shown above.
I've been working with a handy php script, which scans my site and spits out links to all the pages it finds. The problem is, it's also scanning my 'includes' folder, which contains all my .inc.php files.
Obviously I'd rather it ignore this folder when scanning the site, but for the life of me I can't see how to edit the script to tell it to do so.
The script is:
<?php
// starting directory. Dot means current directory
$basedir = ".";
// function to count depth of directory
function getdepth($fn){
return (($p = strpos($fn, "/")) === false) ? 0 : (1 + getdepth(substr($fn, $p+1)));
}
// function to print a line of html for the indented hyperlink
function printlink($fn){
$indent = getdepth($fn); // get indent value
echo "<li class=\"$indent\"><a href=\"$fn\">"; //print url
$handle = fopen($fn, "r"); //open web page file
$filestr = fread($handle, 1024); //read top part of html
fclose($handle); //clos web page file
if (preg_match("/<title>.+<\/title>/i",$filestr,$title)) { //get page title
echo substr($title[0], 7, strpos($title[0], '/')-8); //print title
} else {
echo "No title";
}
echo "</a></li><br>\n"; //finish html
}
// main function that scans the directory tree for web pages
function listdir($basedir){
if ($handle = #opendir($basedir)) {
while (false !== ($fn = readdir($handle))){
if ($fn != '.' && $fn != '..'){ // ignore these
$dir = $basedir."/".$fn;
if (is_dir($dir)){
listdir($dir); // recursive call to this function
} else { //only consider .html etc. files
if (preg_match("/[^.\/].+\.(htm|html|php)$/",$dir,$fname)) {
printlink($fname[0]); //generate the html code
}
}
}
}
closedir($handle);
}
}
// function call
listdir($basedir); //this line starts the ball rolling
?>
Now I can see where the script is told to ignore certain files, and I've tried appending:
&& $dir != 'includes'
...to it in numerous places, but my php knowledge is simply too shaky to know exactly how to integrate that code into the script.
If anyone can help, then you'd be saving me an awfully large headache. Cheers.
Add it this line:
if ($fn != '.' && $fn != '..'){ // ignore these
so it's
if ($fn != '.' && $fn != '..' && $fn != 'includes'){ // ignore these
Your path needs to be absolute. Add it at the top of listdir
function listdir($basedir){
if($basedir == '/path/to/includes') {
return;
} [...]
This also makes sure that only one includes folder will be ignored.
I have created this php script which displays the contents of a designated directory and allows users to download each file. Here is the code:
<?php
if ($handle = opendir('test')) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
echo "<a href='test/$file'>$file\n</a><br/>";
}
}
closedir($handle);
}
?>
This script also displays folders, but when I click a folder, it does display the contents of the folder, but in the default Apache autoindex view.
What I would like the script to do when a folder is clicked, is display the contents, but in the same fashion as the original script does (as this is more editable with css and the like).
Would you know how to achieve this?
Don't create a link to the directory itself, but to a php page which displays the contents.
Change your php code to somthing like:
if(isset($_REQUEST['dir'])) {
$current_dir = $_REQUEST['dir'];
} else {
$current_dir = 'test';
}
if ($handle = opendir($current_dir)) {
while (false !== ($file_or_dir = readdir($handle))) {
if(in_array($file_or_dir, array('.', '..'))) continue;
$path = $current_dir.'/'.$file_or_dir;
if(is_file($path)) {
echo ''.$file_or_dir."\n<br/>";
} else {
echo ''.$file_or_dir."\n<br/>";
}
}
closedir($handle);
}
PS write you html code with double quotes.
You need your HREF to point back to your PHP script, and not the directory. You will then need to update your PHP script to now which directory it needs to read.