Download files from url of site directory - php

Two zip files and Two images are in https://example.com/directory. (Since index.php file is available in this directory we don't know the file names of those files).
Is there any possible way to find names of above four files using PHP or Linux commands?

You must keep in mind: if your web-server disallows to scan a directory then you couldn't get file names. But if the directory is shared in web-server you can get a list of files with using wget command. For example:
wget -nv -r -np '*.*' https://example.com/directory/

Say you have on your webserver example.com a directory like: /multimedia/ and you want to retrieve its contents like mp3, jpg, png, etc - but not the listing index nor tmp index files like i.e: index.html•C=D;O=D:
wget -r -R "*.html*" -np -nd -l 1 example.com/multimedia/
where:
-r # Recursive
-R "*.html*" # Reject tmp and listing html files
-np # Don't ascend to the parent directory
-nd # Don't create parent directories
-l 1 # Only one level deep (multimedia/ folder only)
To learn more: run man wget or wget --help or visit gnu.org WGET

<?php
$files=[];
$folder="/directory/directory/directory/";
if (is_dir($folder)){ // check whether exists or not
$allfiles = glob($folder.'/*.*'); // Read all filenames of $folder directory
foreach($allfiles as $imgFile) {
$files[]=$imgFile; // Putting the names of $folder directory to array one by one
}
}
echo "<pre>";
print_r($files); // printing the file name array to list aal names
echo "</pre>";

I think you don't understant HTTP protocals at all. According to HTTP protocal it doesn't know about any directory/sub-directory. You can't do things as such in HTTP Protocal.
You want to download http://example.com/directory some files for which you don't know the names. For that you can't use PHP as such. You have to depend on external library such as wget etc. or FTP protocal.

<?php
$dir = 'directory';
$filesArr = scandir($dir);
$files = array();
for($i=2; $i<count($filesArr);++$i){
if($filesArr[$i]=="index.php"){ continue; }
$files[] = $filesArr[$i];
}
$zipname = 'file1.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
foreach ($files as $file) {
$zip->addFile($file);
$zip->addFile($dir.'/'.$file, $dir.'/'.$file);
}
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
$zip->close();
exit;
?>

Try this I am using below sample in my project and its working fine for me,
<?php
$directory='directory';
$handler= opendir("$directory"."/");
$i=0;
while (false !== ($file = readdir($handler))) {
if ($file != '.' && $file !='..'){
echo $file.'<br>';
}
}
?>

You can use PHPs scandir Method.
Try this:
<?php
$files = scandir('./');
print_r($files);
This should print all files in the current directory. More information here

Related

Why do scandir, opendir and glob all NOT return my directory contents

I'm currently in the process of creating an application to generate and manage project names based on predefined themes. This application features very basic cloud saving functionality. It's super simple and designed to work without a database by saving the generated save data on files on a server.
In order for the program to download all the saved files I need to list all the saved files in a folder on the server. However, I can't seem to get the expected response from my server. I've tried 3 different ways to list all the files, and NONE of them return any files, which seems very odd to me.
$dir = "WordPress_SecureMode_01/Bubba/";
echo pathinfo($dir, PATHINFO_DIRNAME);
// Open a known directory, and proceed to read its contents
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
echo "filename: $file : filetype: " . filetype($dir . $file) . "\n";
}
closedir($dh);
}
}
$files = scandir('WordPress_SecureMode_01/Bubba/');
foreach($files as $file){
echo $file;
echo pathinfo($file, PATHINFO_FILENAME);
}
$entries = glob('WordPress_SecureMode_01/Bubba/*.txt');
foreach($entries as $entry){
echo $entry;
}
As you can see I'm now using three different methods of retrieving the files. opendir, scandir and glob. All their findings are echoed and thus retrieved by my application. However, the only data my application receives is the output of the pathinfo method at the top of the script. So, the communication between client and server is working fine, but all the options for scanning directory files aren't.
Does anyone have an idea as to why this behaviour is ocurring?
You either want to use an absolute path, if the files are in the same directory:
$dir = __DIR__;
Or a relative path, if they are in the same directory:
$dir = "./";
Here in your code $dir is not a directory and that's the reason the code isn't moving forward.
Please check the path,whether it is dir or not by simply executing
$dir = "WordPress_SecureMode_01/Bubba/";
if (is_dir($dir)) {
echo 'Yes';
}
else{
echo 'No';
}
If it gives you Yes it means its not about path and if it returns you No then please change your path to that folder.

FTP Delete All Folders in Target Directory

What i am trying to do is to delete all files in my target servers folder, the folder all the files are in is: "/public_html/" this directory contains all the target files, i don't want to delete this folder as it must remain the intact, just everything inside.
function ftpDelete($conn, $directory) {
echo "<pre><b>FTP Files on Server:</b>\n";
$filelist = ftp_nlist($conn, $directory);
foreach($filelist as $file) {
// Do not show "." or ".."
if ($file != "." && $file != "..") {
ftp_delete($conn, $directory);
echo $file . "\n";
}
}
echo "</pre>";
}
// Run delete functions ...
ftpDelete($conn, "/public_html/");
// Files out that is still on the server ...
FTP Folders on Server:
/public_html/vendor
/public_html/stats
/public_html/icon
/public_html/images
This code so far will delete all files that is the "public_html" directory, but not any folders, i know from reading the folders need to be empty first, i'm not sure the best way to handle these folders, i didn't see a command that would delete the target folders and it's contents, any help would be appreciated.
You need to append the filename after the directory:
ftp_delete($conn, "$directory/$file");

PHP to extract "some-dir/file.ext" from TAR to "another-dir/file.ext"

I use a .tar.gz created monthly by a 3rd party. I can unzip to a .tar; but I am unable to override the tar directory name when I extract files from the tar.
The tar has a single folder "dirname_latestDate" containing a number of files. I was hoping that by specifying individual files for extraction then the tar's "folder" would be ignored (test script cobbled from code on stackoverflow and elsewhere).
$archive = new PharData($theTar);
// error cheecking excluded
foreach($archive as $entry) {
$extractDir = basename($file) . '/';
if($file->isDir()) {
$dir = new PharData($file->getPathname());
foreach($dir as $child) {
$extract_file = $extractDir . basename($child);
$archive->extractTo('/mypath/my-dir', $extract_file, true);
}
}
}
But this still results in the files being placed in a sub-directory named as per tar folder e.g. /mypath/my-dir/unwanted-tar-dirname/file.ext.
I can copy the file from the sub-dir and then delete but this seems ineffficient and unnecessary. Is there any way to override the Tar folder name on un-tar?
The tar contains one file of about 4MB (uncompressed) and a few other miniscule files.
No, you can't change the output file name directly with extractTo.
You could however use file_put_contents in combination with $phar['filepath]->getContent() to extract the file manually.

Zipping up a folder without extra folders in the zipped file

So, I understand it's pretty easy to zip a folder and its contents given that php.net and stackoverflow are full of sample codes. I am trying to zip up a folder as well. This is my code:
$zip = new ZipArchive;
$zip->open('myzip.zip', ZipArchive::CREATE);
foreach (glob("/Volumes/Data/Users/username/Desktop/Archive/some/thisFolder/*") as $file) {
$zip->addFile($file);
}
$zip->close();
My script is running in a folder, say on Desktop, and I want to zip thisFolder and its contents. The above code WORKS. But, the problem is that when I unzip the myzip.zip created, I get a structure like
Volumes>Data>Users>username>Desktop>Archive>some>thisFolder
and then I find the contents inside the 8th folder (thisFolder) in this case. How can I change this code so that when I unzip myzip.zip,I would straightaway see the folder thisFolder with the contents inside it instead of having to navigate through folders 7 times before getting my content?
I tried to change the path and silly things like that. But, it doesn't work.
Thanks
If you want everything in the file to be a name relative to your starting folder, use chdir() to start from there:
chdir("/Volumes/Data/Users/username/Desktop/Archive/some/thisFolder");
foreach (glob("*") as $file) {
$zip->addFile($file);
}
Actually, I don't think this will work when $file is a subdirectory -- addFile doesn't recurse automatically. There's a comment in the documentation that shows how to write a recursive zip function:
http://www.php.net/manual/en/ziparchive.addemptydir.php
bool ZipArchive::addFile ( string $filename [, string $localname ] )
filename
The path to the file to add.
localname
local name inside ZIP archive.
You can use the pathinfo function to each $file in your loop, in order to retrieve the filename without the path, and then, use it as second parameter to the addFile method.
pathinfo doc here
Here is an example that could solve your problem:
// Create your zip archive
$zip = new ZipArchive;
// open it in creation mode
$zip->open('myzip.zip', ZipArchive::CREATE);
// Loop on all your file
$mask = "/Volumes/Data/Users/username/Desktop/Archive/some/thisFolder";
$allAvailableFiles = glob($mask . "/*")
foreach ($allAvailableFiles as $file)
{
// Retrieve pathinfo
$info = pathinfo($file);
// Generate the internal directory
$internalDir = str_replace($mask, "", $info['dirname']);
// Add the file with internal directory
$zip->addFile($file, $internalDir . "/" . $info['basename']);
}
$zip->close();

wget return downloaded filename

I'm using wget in a php script and need to get the name of the file downloaded.
For example, if I try
<?php
system('/usr/bin/wget -q --directory-prefix="./downloads/" http://www.google.com/');
?>
I will get a file called index.html in the downloads directory.
EDIT: The page will not always be google though, the target may be an image or stylesheet, so I need to find out the name of the file that was downloaded.
I'd like to have something like this:
<?php
//Does not work:
$filename = system('/usr/bin/wget -q --directory-prefix="./downloads/" http://www.google.com/');
//$filename should contain "index.html"
?>
Maybe that's some kind of cheating, but why not :
decide yourself the name of the file that wget should create
indicate to wget that the download should be made to that file
when the download is finished, use that file -- as you already know the name.
Check out the -O option of wget ;-)
For example, running this from the command-line :
wget 'http://www.google.com/' -O my-output-file.html
Will create a file called my-output-file.html.
if your requirement is simple like just getting google.com, then do it within PHP
$data=file_get_contents('http://www.google.com/');
file_put_contents($data,"./downloads/output.html");
On Linux like systems you can do:
system('/usr/bin/wget -q --directory-prefix="./downloads/" http://www.google.com/');
$filename = system('ls -tr ./downloads'); // $filename is now index.html
This works if there is no other process creating file in the ./downloads directory.
I ended up using php to find the most recently updated file in the directory using the following code:
<?php
system('/usr/bin/wget -q --directory-prefix="./downloads/" http://www.google.com/');
$dir = "./downloads";
$newstamp = 0;
$newname = "";
$dc = opendir($dir);
while ($fn = readdir($dc)) {
# Eliminate current directory, parent directory
if (ereg('^\.{1,2}$',$fn)) continue;
$timedat = filemtime("$dir/$fn");
if ($timedat > $newstamp) {
$newstamp = $timedat;
$newname = $fn;
}
}
// $newname contains the name of the most recently updated file
// $newstamp contains the time of the update to $newname
?>

Categories