I've found a good demo code that I was able to make work with what I'm trying to do. But the final product is fairly ugly, and doesn't let me view the files. As far as the "nice" part goes, I have a feeling I should be looking as something more jquery oriented?
When i click on the link for a displayed file, I get a url not found error. The path to the file is incorrect...
This is incorrect and what the script currently tries to navigate to:
http://server/var/www/html/reports/1/Doe_John/2019-04-01/Run_2_Report.pdf
This is correct and works to display the file in the browser:
http://server/reports/1/Doe_John/2019-04-01/Run_2_Report.pdf
Is there a straightforward way to "subtract" out the extra file path portion that is causing the problem? I had to add the {$_SERVER['DOCUMENT_ROOT']} part to make it find the files, but that seems to be what is causing the issue now.
I'm also wanting to sort the files by date, and it's not doing that correctly. The dates are being sorted alphabetically by month. Can this be accomplished with just HTML, or should I again be looking at something like Jquery?
PHP that displays all pdf files in structure:
<?PHP
// Original PHP code by Chirp Internet: www.chirp.com.au
// Please acknowledge use of this code by including this header.
//Test User Vars
$region = "1";
$first_name = "John";
$last_name = "Doe";
function getFileList($dir, $recurse = FALSE)
{
// array to hold return value
$retval = array();
// add trailing slash if missing
if(substr($dir, -1) != "/") $dir .= "/";
// open pointer to directory and read list of files
$d = #dir($dir) or die("getFileList: Failed opening directory $dir for reading");
while(false !== ($entry = $d->read())) {
// skip hidden files
if($entry[0] == ".") continue;
if(is_dir("$dir$entry")) {
$retval[] = array(
"name" => "$dir$entry/",
"type" => filetype("$dir$entry"),
"size" => 0,
"lastmod" => filemtime("$dir$entry")
);
if($recurse && is_readable("{$dir}{$entry}/")) {
$retval = array_merge($retval, getFileList("{$dir}{$entry}/", TRUE));
}
} elseif(is_readable("$dir$entry")) {
$retval[] = array(
"name" => "$dir$entry",
"type" => mime_content_type("$dir$entry"),
"size" => filesize("$dir$entry"),
"lastmod" => filemtime("$dir$entry")
);
}
}
$d->close();
return $retval;
}
?>
<h1>List PDF files with links</h1>
<table class="collapse" border="1">
<thead>
<tr><th>Name</th><th>Type</th><th>Size</th><th>Last Modified</th></tr>
</thead>
<tbody>
<?PHP
$dirlist = getFileList("{$_SERVER['DOCUMENT_ROOT']}/reports/{$region}/{$last_name}_{$first_name}/", TRUE);
foreach($dirlist as $file) {
if($file['type'] != "application/pdf") continue;
echo "<tr>\n";
echo "<td>",basename($file['name']),"</td>\n";
echo "<td>{$file['type']}</td>\n";
echo "<td>{$file['size']}</td>\n";
echo "<td>",date('r', $file['lastmod']),"</td>\n";
echo "</tr>\n";
}
?>
</tbody>
</table>
The second link works because /var/www/html/ is probably the DocumentRoot of your server, if you are using Apache, it is kind of the root of your application.
Related
I am just learning more about using classes in PHP. I know the code below is crap has I need help. Can someone just let me know if I am going in the right direction?
while($entryName=readdir($myDirectory)) {
$type = array("index.php", "style.css", "sorttable.js", "host-img");
if($entryName != $type[0]){
if($entryName != $type[1]){
if($entryName != $type[2]){
if($entryName != $type[3]){
$dirArray[]=$entryName;
}
}
}
}
}
What you seem to want is a list of all the files in your directory that do not have one of four specific names.
The code that most resembles yours that would do it more efficiently is
$exclude = array("index.php", "style.css", "sorttable.js", "host-img");
$dirArray = [];
while ($entryName = readdir($myDirectory)) {
if (!in_array($entryName, $exclude)) {
$dirArray[] = $entryName;
}
}
Alternately, you can dispense with the loop (as written, will include both files and directories in the directory you supply)
$exclude = array("index.php", "style.css", "sorttable.js", "host-img");
$contents = scandir($myDirectory);
$dirArray = array_diff($contents, $exclude);
Edit to add for posterity:
#arkascha had an answer that used array_filter, and while that example was just an implementation of array_diff, the motivation for that pattern is a good one: There may be times when you want to exclude more than just a simple list. It is entirely reasonable, for instance, to imagine you want to exclude specific files and all directories. So you have to filter directories from your list. And just for fun, let's also not return any file whose name begins with ..
$exclude = ["index.php", "style.css", "sorttable.js", "host-img"];
$contents = scandir($myDirectory); // myDirectory is a valid path to the directory
$dirArray = array_filter($contents, function($fileName) use ($myDirectory, $exclude) {
if (!in_array($fileName, $exclude) && strpos('.', $fileName) !== 0) {
return !is_dir($myDirectory.$fileName));
} else {
return false;
}
}
You actually want to filter your input:
<?php
$input = [".", "..", "folderA", "folderB", "file1", "file2", "file3"];
$blacklist = [".", "..", "folderA", "file1"];
$output = array_filter($input, function($entry) use ($blacklist) {
return !in_array($entry, $blacklist);
});
print_r($output);
The output is:
Array
(
[3] => folderB
[5] => file2
[6] => file3
)
Such approach allows to implement more complex filter conditions without having to pass over the input data multiple times. For example if you want to add another filter condition based on file name extensions or file creation time, even on file content.
Ok guys so heres another debug nightmare that I've come across and can't seem to figure out exactly what is going on here -_-
Basically what is happening is that this code returns JSON to my ajax request. Which involves originally an array from the php.
array(
"public_html"=>
array(
"public_html"=>
array(//...other files actually in public html),
),
0 =>
array(
"filename":".ftpquota",
"filesize": 12kb
),
);
So as you can see it's creating a public_html index then adding another with the same name with the actual files inside public_html this is not what I want, I want the original public_html to come back as the files in public_html
/*
Iterates over files and directories recursively
*/
function ftpFileList($ftpConnection, $path="/") {
//create general array to pass back later
$files = array();
//grabs the contents of $path
$contents = ftp_nlist($ftpConnection, $path);
//explode the $path to get correct index to fill in
$secondaryPath = explode('/',$path);
//test if the last index in the array is blank
//if it is pop it from the array
if($secondaryPath[count($secondaryPath) - 1] == "")
array_pop($secondaryPath);
//if the array is larger than or equal to one
if(count($secondaryPath) >= 1){
//we will rewrite $secondaryPath to the last index (actual file name)
$secondaryPath = $secondaryPath[count($secondaryPath) - 1];
}else{
//if it isn't anything we'll make it the path that we originally passed
$secondaryPath = $path;
}
//check for contents
if($contents){
//iterate over the contents
foreach($contents as $currentFile) {
//if the current file is not . or .. we don't need that at all
if($currentFile !== "." && $currentFile !== ".."){
//if there is a period in the currentFile this means it's a file not a directory
if( strpos($currentFile,".") == 0 ) {
if($files[""]){
if($secondaryPath == $currentFile)
$files[""][$secondaryPath][] = ftpFileList($ftpConnection, $path.$currentFile.'/');
else
$files[""][$secondaryPath][$currentFile] = ftpFileList($ftpConnection, $path.$currentFile.'/');
}else{
$files[$secondaryPath][] = ftpFileList($ftpConnection,$path.$currentFile.'/');
}
}else{
//here we know the $currentFile is a file
if($currentFile !== "." && $currentFile !== ".."){
//file in the correct index with a new index which is an array with information
$files[$secondaryPath][] = array(
"file"=>$currentFile,//file name
"filesize"=>humanFileSize(ftp_size($ftpConnection,"/".$path.$currentFile)),//human readable file size
"creation_date"=>date("F d Y g:i:sa",ftp_mdtm($ftpConnection,"/".$path.$currentFile)),//date in a human readable format
"full_path"=>"/".$path.$currentFile//full path of the file so we can access this later
);
}
}
}
}
return $files;//return the array
}
}
I'm hoping this is partially easy to understand, I made a bunch of notes for debugging purposes. I need to iterate and get the files correctly in a nice JSON file so I can iterate over that with JS. It's hard to debug this with the internet I have and testing it in the IDE I am using, I only have a chromebook. (if anyone knows of a good app to use for the chromebook. )
I have this php script which reads mp3 files from the directory:
// Set your return content type
header('Content-type: text/xml');
//directory to read
$dir = ($_REQUEST['dir']);
$sub_dirs = isBoolean(($_REQUEST['sub_dirs']));
if(file_exists($dir)==false){
//echo $_SERVER['DOCUMENT_ROOT'];
//echo "current working directory is -> ". getcwd();
echo 'Directory \'', $dir, '\' not found!';
}else{
$temp = getFileList($dir, $sub_dirs);
echo json_encode($temp);
}
function isBoolean($value) {
if ($value && strtolower($value) !== "false") {
return true;
} else {
return false;
}
}
function getFileList($dir, $recurse){
$retval = array(); // array to hold return value
if(substr($dir, -1) != "/") // add trailing slash if missing
$dir .= "/"; // open pointer to directory and read list of files
$d = #dir($dir) or die("getFileList: Failed opening directory $dir for reading");
while(false !== ($entry = $d->read())) { // skip hidden files
if($entry[0] == "." || $entry[0] == "..") continue;
if(is_dir("$dir$entry")) {
if($recurse && is_readable("$dir$entry/")) {
$retval = array_merge($retval, getFileList("$dir$entry/", true));
}
}else if(is_readable("$dir$entry")) {
$path_info = pathinfo("$dir$entry");
if(strtolower($path_info['extension'])=='mp3'){
$retval[] = array(
"path" => "$dir$entry",
"type" => $path_info['extension'],
"size" => filesize("$dir$entry"),
"lastmod" => filemtime("$dir$entry")
);
}
}
}
$d->close();
return $retval;
}
This file sits in the same directory as the html page which executes the script. For example, I pass the relative path 'audio/mp3' or '../audio/mp3' and it all works well.
Is it possible to make this read directory with absolute path?
For example, if I would pass this: http://www.mydomain.com/someFolder/audio/mp3, and html page which executes the script and the php file would be placed in this location: http://www.mydomain.com/someFolder/
Thank you!
Web root is always just /. You'd never need the hostname or protocol part, and root can be only root of the server, not some folder or file.
If you need some path, like /testthesis/ - there are ways, but it has nothing common with web root.
If you need a filesystem directory for the webroot - it's in the $_SERVER['DOCUMENT_ROOT'] variable.
Basicly what i am trying to accomplish is to get a list of uploaded images from a folder using the editor redactor with the function: imageGetJson
I have managed to get fwrite to add an array in my images.json file. Now the problem is that redactor needs brackets around the input in order to render the images.
So my question is how do i get the brackets around my data?
The upload file i have so far is this:
// This is a simplified example, which doesn't cover security of uploaded images.
// This example just demonstrate the logic behind the process.
// files storage folder
$dir = '../img/uploads/';
$_FILES['file']['type'] = strtolower($_FILES['file']['type']);
if ($_FILES['file']['type'] == 'image/png'
|| $_FILES['file']['type'] == 'image/jpg'
|| $_FILES['file']['type'] == 'image/gif'
|| $_FILES['file']['type'] == 'image/jpeg'
|| $_FILES['file']['type'] == 'image/pjpeg')
{
// setting file's mysterious name
$filename = md5(date('YmdHis')).'.jpg';
$file = $dir.$filename;
// copying
copy($_FILES['file']['tmp_name'], $file);
// displaying file
$array = array(
'filelink' => '/img/uploads/'.$filename,
'thumb' => '/img/uploads/'.$filename,
'image' => '/img/uploads/'.$filename,
);
echo stripslashes(json_encode($array));
$json = stripslashes(json_encode($array)), "\n";
$files = fopen('../img/uploads/images.json','a+');
fwrite($files, $json . "\n");
fclose($files);
}
I have made an array that contains the file location and wrote it to the file images.json
The way i need it to look is like this
[
{"filelink":"image.jpg","thumb":"image.jpg","image":"image.jpg"}
{"filelink":"image.jpg","thumb":"image.jpg","image":"image.jpg"}
{"filelink":"image.jpg","thumb":"image.jpg","image":"image.jpg"}
{"filelink":"image.jpg","thumb":"image.jpg","image":"image.jpg"}
]
Only it adds like this:
[]
{"filelink":"image.jpg","thumb":"image.jpg","image":"image.jpg"}
{"filelink":"image.jpg","thumb":"image.jpg","image":"image.jpg"}
{"filelink":"image.jpg","thumb":"image.jpg","image":"image.jpg"}
Hope someone can help me with this because i cant figure it out.
Thanks in advance :D
I found another solution: just change the data.json in a php-file data.php which reads the directories you want to list and then convert to json and echo.
Here is what I use now (demo-version, cause my paypal isn't running yet)
(path should be set according to your settings)
In the page where you load the redactor:
imageGetJson: 'redactor901trial/demo/json/data.php'
$path = 'redactor901trial/demo/json/';
$upload_dir = 'images/';
$handle = opendir($upload_dir);
while ($file = readdir($handle)) {
if(!is_dir($upload_dir.$file) && !is_link($upload_dir.$file)) {
$docs[] = $file;
}
}
sort($docs);
foreach($docs as $key=>$file){
$array[] = array(
'filelink' => $path.$upload_dir.$file,
'thumb' => $path.$upload_dir.$file,
'image' => $path.$upload_dir.$file,
'folder' => 'Folder 5'
);
}
echo stripslashes(json_encode($array));
Hope this helps and it is not too late ;)
Regards
Steven
I'm really new to PHP but what I want to do is make a dynamic table of contents for some of my companies job offerings.
So if i put all the pdfs of the job descriptions in a folder called ../jobops with the php file located in root directory what would I need to do.
<?php
$directory = "/jobops";
$contents = scandir($directory);
if ($contents) {
foreach($contents as $key => $value) {
if ($value == "." || $value == "..") {
unset($key);
}
}
}
echo "<ul>";
foreach($contents as $k => $v) {
echo "<li>link text</li>";
}
echo "</ul>";
?>
Should work. Takes the directory, scans it, maps all the filenames into an array $contents removes the relative urls (the "." and "..") and then echoes them out.
Remember that foreach is relatively expensive, though; so you may wish to simply unset $contents[0] and $contents[1].
Edited in response to the following (from the OP):
Warning:
scandir(www.markonsolutions.com/jobops)
[function.scandir]: failed to open
dir: No such file or directory in
/home/content/t/i/m/timhish/html/test.php
on line 5 Warning: scandir()
[function.scandir]: (errno 2): No such
file or directory in
/home/content/t/i/m/timhish/h/i/s/h/html/test.php
on line 5 Warning: Invalid argument
supplied for foreach() in
/home/content/t/i/m/timhish/html/test.php
on line 15
I changed ti from "/jobops"
thinking it was a relative directory
thing but apparently that's not it. also
im not sure what the
/home/content....... thing is but i am
currently hosted with go daddy maybe
thats how they store things?
The $directory variable is relative to where the script is being called. In my case, this runs from the root folder so it should be, for me, $directory = "jobops" assuming the folder and script are stored in the same place. Without knowing your server's directory structure I can't really help you, but I would suggest ruling out a problem with the scandir() function.
To do this, create a folder in the same directory as your script called whatever you like, populate it with at least one image (so that the following if() doesn't unset the entire array) and see if that works. If it does then you're stuck with finding the relative path to your folder. If it doesn't then I'm stuck myself.
The SPL (PHP5) provides a nice interface to directory traversal:
// whitelist of valid file types (extension => display name)
$valid = array(
'pdf' => 'PDF',
'doc' => 'Word'
);
$files = array();
$dir = new DirectoryIterator($directory_path);
foreach($dir as $file)
{
// filter out directories
if($file->isDot() || !$file->isFile()) continue;
// Use pathinfo to get the file extension
$info = pathinfo($file->getPathname());
// Check there is an extension and it is in the whitelist
if(isset($info['extension']) && isset($valid[$info['extension']]))
{
$files[] = array(
'filename' => $file->getFilename(),
'size' => $file->getSize(),
'type' => $valid[$info['extension']], // 'PDF' or 'Word'
'created' => date('Y-m-d H:i:s', $file->getCTime())
);
}
}
take a look at fnmatch() or glob() functions.
(i'd have liked to post it as a comment, but the link would have been too long)
<?php
// open this directory
$myDirectory = opendir(".");
// get each entry
while($entryName = readdir($myDirectory)) {
$dirArray[] = $entryName;
}
// close directory
closedir($myDirectory);
// count elements in array
$indexCount = count($dirArray);
Print ("$indexCount files<br>\n");
// sort 'em
sort($dirArray);
// print 'em
print("<TABLE border=1 cellpadding=5 cellspacing=0 class=whitelinks>\n");
print("<TR><TH>Filename</TH><th>Filetype</th><th>Filesize</th></TR>\n");
// loop through the array of files and print them all
for($index=0; $index < $indexCount; $index++) {
if (substr("$dirArray[$index]", 0, 1) != "."){ // don't list hidden files
print("<TR><TD>$dirArray[$index]</td>");
print("<td>");
print(filetype($dirArray[$index]));
print("</td>");
print("<td>");
print(filesize($dirArray[$index]));
print("</td>");
print("</TR>\n");
}
}
print("</TABLE>\n");
?>
seems to be working but I need to tweak it to only search a sub dir and only *.pdf files