2

I host my site on a shared hosting, which lately changed the server to safe mode (without even notifying that). I use a feature that download files from the server, using the readfile() function (I use php). Now, in safe_mode, this function is no longer available. Is there a replacement or a workaround to handle the situation that the file will be able to be downloaded by the user?

Thanks

Maor Barazany
  • 761
  • 2
  • 11
  • 21
  • Not working, I already tried it but I get a blank Word screen for .docx files, or just an error for pdf files etc. – Maor Barazany Jun 13 '11 at 10:38
  • What error message do you get? Given that [`safe_mode` is deprecated](http://www.php.net/manual/en/ini.sect.safe-mode.php), you might want to switch hosts if they just enable it recently. In any case, drop your hoster an email asking to relax `safe_mode`. – Gordon Jun 13 '11 at 10:49
  • It won't help, since they claim that it reduces hacks to the servers, and it is shared hosting, so I can't do much to convince them - this is their new policy, I can just switch hosts if I want, but I have there about 20 sites of customers, and start moving all of them will be a headache now. I wonder if there is a workaround to handle the file download, about that bloody hosting I will think later on what to do.. – Maor Barazany Jun 13 '11 at 10:58
  • The error I get is this - Warning>: readfile() has been disabled for security reasons in /home/full/path/to/my/script.php on line 146 – Maor Barazany Jun 13 '11 at 11:00
  • @Maor switching might be a slight headache, but telling the hoster that he will lose 20 additional customers if they dont offer a solution might make them want to reconsider. And like I said, it's deprecated, so if they ever want to upgrade to php.next, they will have to find another solution anyways. – Gordon Jun 13 '11 at 11:16
  • 4
    In this case, `readfile()` is not really affected by safe mode. [Docs](http://lv.php.net/manual/en/features.safe-mode.functions.php) say that file and dir must belong to the same user that executes script, that's what is checked in *safe mode*. In this case, `readfile()` is completely disabled, which is rather being done by `disable_functions`. – binaryLV Jun 13 '11 at 12:16
  • @Gordon - Since this is a shared hosting, I have all my sites there in 2 accounts, so as far as the hosting company concerns, they will lose 1 client (me) with two paid accounts. Their solution is to upgrade the account from shared to VPS, but it is 12x more expensive... – Maor Barazany Jun 13 '11 at 16:27
  • @binaryLV - so if they disabled the readfile() function with disable_functions and not with the safe mode, it is still not solving the issue, since they are not going to allow again the use of this function. – Maor Barazany Jun 13 '11 at 16:29
  • 1
    @Maor, while it does not solve the problem, it might guide you in the right direction. Knowing the cause of the problem is a part of solution. – binaryLV Jun 13 '11 at 16:40

2 Answers2

8

As I wrote in comments, readfile() is disabled by including it in disable_functions php.ini directive. It has nothing to do with safe mode. Try checking which functions are disabled and see if you can use any other filesystem function(-s) to do what readfile() does.

To see the list of disabled functions, use:

var_dump(ini_get('disable_functions'));

You might use:

// for any file
$file = fopen($filename, 'rb');
if ( $file !== false ) {
    fpassthru($file);
    fclose($file);
}

// for any file, if fpassthru() is disabled
$file = fopen($filename, 'rb');
if ( $file !== false ) {
    while ( !feof($file) ) {
        echo fread($file, 4096);
    }
    fclose($file);
}

// for small files;
// this should not be used for large files, as it loads whole file into memory
$data = file_get_contents($filename);
if ( $data !== false ) {
    echo $data;
}

// if and only if everything else fails, there is a *very dirty* alternative;
// this is *dirty* mainly because it "explodes" data into "lines" as if it was
// textual data
$data = file($filename);
if ( $data !== false ) {
    echo implode('', $data);
}
binaryLV
  • 9,002
  • 2
  • 40
  • 42
  • These are the disabled functions - "readfile, system, shell_exec, proc_terminate, proc_nice, proc_open, pclose, popen, passthru, pcntl_fork, pcntl_exec, posix_kill, pcntl_signal, ini_restore, posix_getpwuid, escapeshellarg, escapeshellcmd. I'm going to try your suggestions from above – Maor Barazany Jun 13 '11 at 16:34
  • you are a king! the fpassthru seems to be working just great. Many many thanks. I wanted to also vote up for it, but I can't till I have 2 more reputation score (new user here..) – Maor Barazany Jun 13 '11 at 16:39
1

I assume you are using readfile to load remote files, as you said "from the server". If that is correct, your problem is not safe mode but that opening URLs with normal php file functions is not permitted anymore (setting allow_url_fopen disabled).

In that case, you can use PHP's curl functions to download files. Also, file_get_contents is a valid alternative.

cweiske
  • 30,033
  • 14
  • 133
  • 194
  • Well, It is a small plugin I use that uses the readfile() function to download a file from the site (server) to the user's pc. It all worked ok till recently the hosting company enabled safe_mode. This is the error message I get - Warning>: readfile() has been disabled for security reasons in /home/full/path/to/my/script.php on line 146 – Maor Barazany Jun 13 '11 at 11:03