Okay, I've been searching for a way to list directories and files, which I've figured out and am utilizing code I found here on StackOverflow (Listing all the folders subfolders and files in a directory using php).
So far I've altered code found in one of the answers. I've been able to remove file extensions from both the path and the file name using preg_replace, capitalize the file names using ucwords, and switch out dashes for spaces using str_replace.
What I'm having trouble with now is wrapping the whole thing in a properly nested HTML list. I've managed to set it up so it's wrapped in a list, but it doesn't use nested lists where needed and I can't, for the life of me, figure out how to capitalize the directory names or replace any dashes within the directory name.
So, the questions are, if anyone would be so kind:
How do I wrap the output in properly nested lists?
How do I capitalize directory names while removing the preceding slash and replace dashes or underscores with spaces?
I've left the | within the $ss variable intentionally. I use it as a marker of sorts when I want to throw in characters that will identify where it shows up during trial and error (example $ss = $ss . "<li>workingOrNot").
I'm using:
<?php
$pathLen = 0;
function prePad($level) {
$ss = "";
for ($ii = 0; $ii < $level; $ii++) {
$ss = $ss . "| ";
}
return $ss;
}
function dirScanner($dir, $level, $rootLen) {
global $pathLen;
$filesHidden = array(".", "..", '.htaccess', 'resources', 'browserconfig.xml', 'scripts', 'articles');
if ($handle = opendir($dir)) {
$fileList = array();
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != ".." && !in_array($entry, $filesHidden)) {
if (is_dir($dir . "/" . $entry)) {
$fileList[] = "F: " . $dir . "/" . $entry;
}
else {
$fileList[] = "D: " . $dir . "/" . $entry;
}
}
}
closedir($handle);
natsort($fileList);
foreach($fileList as $value) {
$displayName = ucwords ( str_replace("-", " ", substr(preg_replace('/\\.[^.\\s]{3,5}$/', '', $value), $rootLen + 4)));
$filePath = substr($value, 3);
$linkPath = str_replace(" ", "%20", substr(preg_replace('/\\.[^.\\s]{3,5}$/', '', $value), $pathLen + 3));
if (is_dir($filePath)) {
echo prePad($level) . "<li>" . $linkPath . "</li>\n";
dirScanner($filePath, $level + 1, strlen($filePath));
} else {
echo "<li>" . prePad($level) . "" . $displayName . "</li>\n";
}
}
}
}
I feel like these answers should be simple, so maybe I've been staring at it too much the last two days or maybe it has become Frankenstein code.
I'm about out of trial and error and I need help.
foreach($fileList as $value) {
$displayName = ucwords ( str_replace("-", " ", substr(preg_replace('/\\.[^.\\s]{3,5}$/', '', $value), $rootLen + 4)));
$filePath = substr($value, 3);
$linkPath = str_replace(" ", "%20", substr(preg_replace('/\\.[^.\\s]{3,5}$/', '', $value), $pathLen + 3));
if (is_dir($filePath)) {
// Do not close <li> yet, instead, open an <ul>
echo prePad($level) . "<li>" . $linkPath; . "<ul>\n";
dirScanner($filePath, $level + 1, strlen($filePath));
// Close <li> and <ul>
echo "</li></ul>\n";
} else {
echo "<li>" . prePad($level) . "" . $displayName . "</li>\n";
}
}
I guess you're opening the main before call the function and closing it at the end.
Related
I have one little question, this is my code to list all files from a folder and subfolders;
if ($handle = opendir($dir)) {
$allFiles = array();
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
if (is_dir($dir . "/" . $entry)){
$allFiles[] = "D: " . $dir . "/" . $entry;
}else{
$extension = strtoupper(pathinfo($entry, PATHINFO_EXTENSION));
$fileNoExten = pathinfo($entry, PATHINFO_FILENAME);
$directory = substr(str_replace('/', ' > ', $dir), $rootLenOnce + 3);
$listagem .= '<tr>';
$listagem .= "<td><a href='../" . $dir . "/" . $entry . "' ' target='_blank'>" . $entry . "</a></td>";
//$listagem .= "<td><small>" . $directory . "</small></td>";
$listagem .= "<td>" . $extension . "</td>";
$listagem .= "<td><a class='download-cell' href='../".$dir ."/". $entry."' ' download> <i class='fa fa-download' ></i></a></td>";
$listagem .= "<td class='display-none'>" . $fileNoExten . "</td>";
$allFiles[] = "F: " . $dir . "/" . $entry;
$listagem .= '</tr>';
echo "<pre>"; print_r(glob("*.pdf")); echo "</pre>";
}
}
}
closedir($handle);
foreach($allFiles as $value){
$displayName = substr($value, $rootLen + 4);
$fileName = substr($value, 3);
$linkName = str_replace(" ", "%20", substr($value, $pathLen + 3));
if (is_dir($fileName)) {
myScanDirPdf($fileName, $level + 1, strlen($fileName),$rootLenOnce);
}
}
}
return $listagem;
}
what i need is to filtrate the search, to search only .pdf files.
Someone can help me plz!
Thks!
i try with the glob function, but not with great results.
Thks!
When you are looping through each file, you can use
if(stripos($fileName, ".pdf"))
Hope this will help
I have one more suggestion in listing all the files and subfolders.
You can use Recursive Iterator
$folderName = $_POST['folderName'];
$dir = new RecursiveDirectoryIterator($folderName);
$it = new RecursiveIteratorIterator($dir);
foreach ($it as $fileinfo) {
if ($fileinfo->isDir()) {
}elseif ($fileinfo->isFile()) {
$fileName = $fileinfo->getFileName();
if(stripos($fileName, ".pdf")) {
//do what you need to do
}
}
}
I'm newbie about programming, so this is my issue. I am trying to build a recursive php spider usind Simple HTML DOM Parser, crawling into a certain website and returning a list of pages including 2xx, 3xx, 4xx and 5xx. I've been searching several days for a solution but (maybe due to my low experience) I haven't found anything working. My actual code finds all the links on the root/index page, however i would like to be able to find links inside those previously found links recursively and so on, for example to level 5. Assuming the root page is level 0, the recursive function I wrote only shows me level 1 links, repeating them 5 times. Any help appreciated. Thanks.
<?php
echo "<strong><h1>Sitemap</h1></strong><br>";
include_once('simple_html_dom.php');
$url = "http://www.gnet.it/";
$html = new simple_html_dom();
$html->load_file($url);
echo "<strong><h2>Int Links</h2></strong><br>";
foreach($html->find("a") as $a)
{
if((!(preg_match('#^(?:https?|ftp)://.+$#', $a->href)))&&($a->href != null)&&($a->href != "javascript:;")&&($a->href != "#"))
{
echo "<strong>" . $a->href . "</strong><br>";
}
}
echo "<strong><h2>Ext Links</h2></strong><br>";
foreach($html->find("a") as $a)
{
if(((preg_match('#^(?:https?|ftp)://.+$#', $a->href)))&&($a->href != null)&&($a->href != "javascript:;")&&($a->href != "#"))
{
echo "<strong>" . $a->href . "</strong><br>";
}
}
//recursion
$depth = 1;
$maxDepth = 5;
$recurl = "$a->href";
$rechtml = new simple_html_dom();
$rechtml->load_file($recurl);
while($depth <= $maxDepth){
echo "<strong><h2>Link annidati livello $depth</h2></strong><br>";
foreach($rechtml->find("a") as $a)
{
if(($a->href != null))
{
echo "<strong>" . $a->href . "</strong><br>";
}
}
$depth++;
}
//csv
echo "<strong><h1>Google Crawl Errors from CSV</h1></strong><br>";
echo "<table>\n\n";
$f = fopen("CrawlErrors.csv", "r");
while (($line = fgetcsv($f)) !== false) {
echo "<tr>";
foreach ($line as $cell) {
echo "<td>" . htmlspecialchars($cell) . "</td>";
}
echo "</tr>\n";
}
fclose($f);
echo "\n</table>";
?>
Try this:
I call this routine in a basic scraper to recursively find all of the links across the site. You'll have to put in some logic to prevent it from crawling external sites that are linked to from pages on your site, else you'll be running forever!
Note, I did get the majority of this code from another SO thread a while back, so the answers are out there.
function crawl_page($url, $depth = 2){
// strip trailing slash from URL
if(substr($url, -1) == '/') {
$url= substr($url, 0, -1);
}
// which URLs have we already crawled?
static $seen = array();
if (isset($seen[$url]) || $depth === 0) {
return;
}
$seen[$url] = true;
$dom = new DOMDocument('1.0');
#$dom->loadHTMLFile($url);
$anchors = $dom->getElementsByTagName('a');
foreach ($anchors as $element) {
$href = $element->getAttribute('href');
if (0 !== strpos($href, 'http')) {
// build the URLs to the same standard - with http:// etc
$path = '/' . ltrim($href, '/');
if (extension_loaded('http')) {
$href = http_build_url($url, array('path' => $path));
} else {
$parts = parse_url($url);
$href = $parts['scheme'] . '://';
if (isset($parts['user']) && isset($parts['pass'])) {
$href .= $parts['user'] . ':' . $parts['pass'] . '#';
}
$href .= $parts['host'];
if (isset($parts['port'])) {
$href .= ':' . $parts['port'];
}
$href .= $path;
}
}
crawl_page($href, $depth - 1);
}
// pull out the actual page name without any parent dirs
$pos = strrpos($url, '/');
$slug = $pos === false ? "root" : substr($url, $pos + 1);
echo "slug:" . $slug . "<br>";
}
If you look at many of my questions, you will see that sometimes I don't ask the best questions or I am in such a rush that I don't see the answer that is right in front of me the whole time. If this is another one of those questions, please be kind as some other people haven't been the nicest. Now onto the question.
I have been in the process of creating a file listing viewer type thing for the past week or so. At this point, its all great but I needed to add a search function. I did so by using array_search(). The only problem is that this function requires you to put in the EXACT name of the file rather than part of it.
Here is the problem. I have tried numerous solutions, and to be frank, my PHP skills aren't the most professional. I have tried for array_filters and for loops with strpos. Nothing at this point works. My code is below:
<?php
//error_reporting(0);
//ini_set('display_errors', 0);
//$dir = $_SERVER["DOCUMENT_ROOT"] . '/';
$dir = getcwd();
$files = $files = array_slice(scandir($dir), 2);
$number = count($files);
sort($files);
$images = array();
$an = count($images);
$query = $_GET['q'];
$searchimages = array();
$san = count($searchimages);
$r = array();
if ($query) {
for ($w = 0; $w <= $number; $w++){
$rnum = count($r);
if (strpos($files[$w], $query) !== false) {
$r[$rnum++] = $files[$w];
}
}
if ($r != null) {
if (substr($files[$r], -5) == ".jpeg" || substr($files[$r], -4) == ".png" || substr($files[$r], -4) == ".jpg" || substr($files[$r], -4) == ".gif") {
$searchimages[$san++] = $files[$r];
echo "<a href='#" . $files[$r] . "'>" . $files[$r] . "</a><br>";
} else {
echo "<a href='" . $files[$r] . "'>" . $files[$r] . "</a><br>";
}
for ($z = 0; $z <= $san; $z++)
echo "<a name='" . $searchimages[$z] . "'>" . "<a href='" . $searchimages[$z] . "' target='_blank'>" . "<img src='" . $searchimages[$z] . "'>" . "</img></a>";
} else {
echo "No results found. Please try a different search" . "<br>";
}
} else {
for ($x = 0; $x <= $number; $x++) {
if (substr($files[$x], -5) == ".jpeg" || substr($files[$x], -4) == ".png" || substr($files[$x], -4) == ".jpg" || substr($files[$x], -4) == ".gif") {
$images[$an++] = $files[$x];
echo "<a href='#" . $files[$x] . "'>" . $files[$x] . "</a><br>";
} else {
echo "<a href='" . $files[$x] . "'>" . $files[$x] . "</a><br>";
}
}
for ($y = 0; $y <= $an; $y++) {
echo "<a name='" . $images[$y] . "'>" . "<a href='" . $images[$y] . "' target='_blank'>" . "<img src='" . $images[$y] . "'>" . "</img></a>";
}
}
?>
Currently there are over 2,000 files and they have all sorts of random characters in them. These characters range from dashes to exclamation marks to letters and numbers as well as periods and many more. I don't have control over these file names and they have to stay exactly the same.
If you look at the code, I first get all the file names and store them in an array,
$files
Then I check if the search parameter is supplied in the url,
?q=insert-search-terms-here
After that, if it is supplied, I will search for it (this is where the problem is). If it isn't supplied, I simply get the file names from the array and check if they are an image. If they are, I print them all out at the bottom of the page in the form of thumbnails and make their link at the top a page link that scrolls you down to the location of the image. If it isn't an image, it takes you directly to the file. Note that the thumbnails are links to the actual image.
What is supposed to happen when it searches is that basically does what it would do if it weren't searching, but it limits itself to files that contain the string "foobar" for example.
When it searches but doesn't find anything, it prints out that it didn't find anything and that the user should search again.
If anyone could help with this, it would be greatly appreciated. Like I said at the beginning, please be kind if its a dumb mistake.
Best Regards,
Emanuel
EDIT:
This article now obviously has an answer and for those finding this article on Google or what have you, I want you to read the comments in the answer post as well as the answer as they provide KEY information!!
You may want to use preg_grep. Replace this:
for ($w = 0; $w <= $number; $w++){
$rnum = count($r);
if (strpos($files[$w], $query) !== false) {
$r[$rnum++] = $files[$w];
}
}
with this:
$r = preg_grep('/\Q' . $query . '\E/', $files);
Example:
$files = array(
'foo.bar',
'barfoo.baz',
'baz.fez',
'quantum-physics.ftw',
);
$query = 'foo';
$r = preg_grep('/\Q' . $query . '\E/', $files);
print_r($r);
Output:
Array
(
[0] => foo.bar
[1] => barfoo.baz
)
The preg_match below can be read "match any string ending with a dot followed by jpeg, png, jpg or gif" (the dollar sign can be translated into "end of the string").
if ($query) {
$r = preg_grep('/\Q' . $query . '\E/', $files);
if ($r != null) {
foreach($r as $filename) {
if (preg_match('/\.(jpeg|png|jpg|gif)$/', $filename)) {
// File is an image
echo "$filename is an image<br/>";
// Do stuff ...
} else {
// File is not an image
echo "$filename is NOT an image<br/>";
// Do stuff ...
}
}
// ... Do more
} else {
echo "No results found. Please try a different search" . "<br>";
}
}
http://www.wordinn.com/solution/108/php-getting-part-string-after-and-given-sub-string-or-character
this might be help ful..
function strafter($string, $substring) {
$pos = strpos($string, $substring);
if ($pos === false)
return $string;
else
return(substr($string, $pos+strlen($substring)));
}
Something like this will work even for associative array.
foreach ($members as $user){
$Match = substr($user['column'][0], strpos($user['column'][0], "#") + 1);
$final_Array[$i]=$Match;
$i++;
}
print_r($final_Array)
I do want to decrease the first part of the folders which are contained on the server when I delete a field in a database.
my folders are like : 1-Guerlain, 2-Chanel, 3-Diesel. So when the first folder is deleted I want for the other folders to be like 1-Chanel, 2-Diesel.
This is my code :
foreach (new DirectoryIterator($path) as $file)
{
if($file->isDot()) continue;
if($file->isDir())
{
$parts = explode('-', $file->getFilename());
if ($parts[0] > $_GET['id_folder']) {
$old = "./" . $parts[0] . "-" . $parts[1] . "";
$new = "./" . ($parts[0] - 1) . "-" . $parts[1] . "";
rename($old, $new);
}
}
}
But this gives me the following error : Warning: rename(./2-Chanel,./1-Chanel) [function.rename]: No error in C:\wamp\www\pcqsp-scratch\admin.php on line 196 and the folder doesn't be renamed.
How can I achieve this ? Thank you.
You need the full path for rename()
$parts = explode('-', $file->getFilename());
$path = $file->getPath();
$old = $path . DIRECTORY_SEPARATOR . $parts[0] . "-" . $parts[1] . "";
$new = $path . DIRECTORY_SEPARATOR . ($parts[0] - 1) . "-" . $parts[1] . "";
rename($old, $new);
My function looks like that
protected function make_js_link($list, $folder, $parentdir = "js") {
$links = array();
$list = explode(',', $list);
foreach ($list as $name) {
$dir = $parentdir . "/";
if (is_string($folder))
echo $folder . "/";
$links[] = '<script src="' . $dir . trim($name) . '.js"></script>' . "\n";
}
echo implode(" ", $links);
}
So when js file located in $parentdir I'm calling like that
$this->make_js_link('ckeditor', 0, 'incl/editor');
If file located in parentdir/another_dir, then calling like that
$this->make_js_link('jquery', 'adapters', 'incl/editor');
The problem is, PHP escapes this part in both cases: even if I have folder variable with exact string value:
if (is_string($folder))
echo $folder . "/";
Where I did wrong?
You did echo instead of
$dir = $parentdir . "/";
if (is_string($folder))
$dir.= $folder . "/";