Downloading a directory

<?php
$filepath = "targetDir";
$filesize = filesize($filepath);
$path_parts = pathinfo($filepath);
$filename = $path_parts["basename"];
$extension = $path_parts["extension"];

header("Pragma: public");
header("Expires: 0");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=$filename");
header("Content-Transfer-Encoding: binary");
header("Content-Length: $filesize");

ob_clean();
flush();
readfile($filepath);

My code above is for making a directory download.

As the result of it, the client downloads a file “targetDir”, although it is a directory in the server.

How can I make it download a directory?

Try this:

https://www.php.net/manual/en/function.glob.php

I made the code below after reading the quote above.

<?php
foreach (glob("*.*") as $filename) {
    echo "$filename size " . filesize($filename) . "<br>";
}

The result of the code above produces all files in the directory like the quote below.

But it doesn’t produces any directory although it has directory1 named “dir1” and directory2 “dir2” in the same directory.
Can I make my target result below with your help?

Try this:

<?php
declare(strict_types=1);
error_reporting(-1);
ini_set('display_errors', '1');

$aFiles = glob("*");
  foreach ($aFiles as $filename) :
    if( is_dir($filename) ) :
      $aDirs[]  = $filename;
    else:  
      $aFiles[] = $filename;
    endif;  
  endforeach;

  echo '<h3>$aDirs: </h3>'   .implode('<br>', $aDirs);
  echo '<br><br>';
  echo '<h3>$aFiles:  </h3>' .implode('<br>', $aFiles);

As I try your code for displaying directories, it works fine.
It’s time to back to original quesion about doownloading a directory.

Ooops I found someting wrong.

$filepath = "target.php";
$filesize = filesize($filepath);
$path_parts = pathinfo($filepath);
$filename = $path_parts[-"basename"-];
$extension = $path_parts[-"extension"-];

header("Pragma: public");
header("Expires: 0");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=$filename");
header("Content-Transfer-Encoding: binary");
header("Content-Length: $filesize");

ob_clean();
flush();
readfile($filepath);

The code above works fine. but as I add error_reporting like the below.
it says something wrong when I open the target.php with sudo nano after it downloaded in the client.

declare(strict_types=1);
error_reporting(-1);
ini_set('display_errors', '1');

$filepath = "target.php";
$filesize = filesize($filepath);
$path_parts = pathinfo($filepath);
$filename = $path_parts[-"basename"-];
$extension = $path_parts[-"extension"-];

header("Pragma: public");
header("Expires: 0");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=$filename");
header("Content-Transfer-Encoding: binary");
header("Content-Length: $filesize");

ob_clean();
flush();
readfile($filepath);

The code above is in PHP5.
Something wrong is the code below.

<br />
<b>Notice</b>:  ob_clean() [<a href='ref.outcontrol'>ref.outcontrol</a>]: faile$

It seems something wrong in ob_clean clause.

ob_clean();

I don’t have no idea for fixing the clause above.

Should I remove the 3 lines regarding errors below for correct downloading of the file “target.php” with correct contents?

declare(strict_types=1);
error_reporting(-1);
ini_set('display_errors', '1');

Check the Free Online PHP Manual:

https://www.php.net/manual/en/function.ob-clean.php

[off-topic]
Why are you trying to use PHP 7 specific functions, statements, etc that were not implemented in PHP 5?
[/off-topic]

I have some projects in my old server PHP5.
I am on the way of immigrations of them to a new server PHP7.
When I do work, I am more convenient in the old server at the moment…
So I do work in the old server for new server, and moving it to a new server.
AS possible as I can, I make the code compatible both PHP5 and PHP7.

Rarely I can use the code below.

if (PHP_VERSION > '5.4') { 

} else {

}

I can move the files with a USB.
but
Now I think that downloading the projects to the new server is going to be a good way.
That is why I made this post “Downloading a directory”.

The proverb “Necessity is the mother of invention” comes up to my think just ago.

When I finish the immigrations, I will do work in the new server PHP7.
And the old-server will be depreciated.

The quote below is from the page of the manual above.

Is the below statement correct?

What does the quote below mean?
What is “output buffer”?
Would you, please, rephrase it for me?

The output buffer clears memory. Following PHP statements are bundled together and can be output all together rather than one at a time. Try remming ob_clean(); and see if the error messages change.

Also try inserting echo __line__; die; to try and pinpoint the errors if specific line numbers are not shown.

Can you expand on exactly what you mean by new and old servers.

Do you mean two different computers both running localhost or are they online?

Have you access to a remote online server? If not there are free remote servers available.

AS possible as I can, I make the code compatible both PHP5 and PHP7.

Some PHP 7 code will produce errors when used on PHP 5. Just leave the old scripts, copy to the new PHP 7 server, set maximum error reporting and try to fix the new script using PHP 7 latest features.

The code below which is added “cho line; die;” in front of ob_clean() says “20”.

echo __line__; die;ob_clean();
flush();
readfile($filepath);

If I added it just after ob_clean() like the below code, it says the quote below.

ob_clean();
echo __line__; die;
flush();
readfile($filepath);

This means error line is 20 “ob_clean();”.
Thanks for teaching me how to pinpoint the error line.
You’ve done this some days ago. but now I understand your intention more clearly.

1 Like

The above quote is same in meaning as the quote below?

1 Like

What does it mean by remming?
I can’t find it in a dictionary.

Does it mean “removing”?

I have two computers and they are web-servers each.

Old server means my server in PHP5.
New server means my server in PHP7.

Usually I open a file on the servers with “localhost” but sometimes I open a file on the servers online.

Both servers are online. but Nobody but I visit the two servers for testing.

1 Like

Placing a remark in front to prevent operation.

<?php
# single line remark
// alternative single line remark
/* another Inline remark */
/*
Multiple line remark
Ideal for marking large blocks
*/
declare(strict_types=1);
error_reporting(-1);
ini_set('display_errors', '1');

Anyway I have no idea till the moment for any code of downloading a file with the code
above of error_reporting

I will use just the code below because it works fine although it has no error_reporting.

$filepath = "target.php";
$filesize = filesize($filepath);
$path_parts = pathinfo($filepath);
$filename = $path_parts[-"basename"-];
$extension = $path_parts[-"extension"-];

header("Pragma: public");
header("Expires: 0");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=$filename");
header("Content-Transfer-Encoding: binary");
header("Content-Length: $filesize");

ob_clean();
flush();
readfile($filepath);

As the locals say here “up to you” :slight_smile:

I find it is worth including error reporting because errors are instantly displayed. New error messages can take time to resolve and once resolved are usually not repeated.

Without error reporting it is like programming with blinkers, not seeing all that is happening and only seeing a restricted view which could crash at anytime.

Yes, That’s true.
Now I think that the slow is the fast at last because it is the long way while I thought I had to go quickly some years ago.

The expression should be remembered.

But at the moment, I can’t get downloading the correct contents of the file with the error_reporting.

Please give me more clearly on this.

Please supply a link to the file and I will try and use your script to download the file.

Please note that according to the readfile() documentation the parameter expected is a file and not a directory.

If as the title of this topic says “Downloading a directory” the readfile() is not the correct function to use.