views:

186

answers:

5

My script puts together a set of htaccess rules based on information passed into it and gives the user a downloadable text file with the rules printed out inside. The idea is that an administrator fills out some form information, clicks a downloadable link, gets a text file with the rules printed out inside, opens the file, copies the rules and pastes them into the htaccess file of their domain.

I've managed to put together the script that produces these rules. However, the text file seems to ignore all newline characters that I print to it. The tabs work, but the newlines do not. It must have something to do with the encoding I'm using with the header() function calls, but I'm not sure what I'm doing wrong. No amount of Googling as seemed to point me in the right direction. Any input would be appreciated.

Here's the code:

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="htaccess.txt"'); 
header('Content-Transfer-Encoding: binary');

$id = addslashes( $_GET['id']);
$location = addslashes( $_GET['location'] ); 
$location = substr($location, strpos($location, '/', 9 ) + 1 ) . ( ( substr( $location, strlen($location) - 1 ) == '/' ) ? '' : '/' );
$regEx = '([0-9a-zA-Z-_]*)';
$lines = array();

for( $x = 0; $x < 10; $x++ ) {
    $line = 'RewriteRule ^' . $location;
    for( $y = 1; $y <= $x; $y++ )
     $line .= $regEx . '/';
    $line .=  '*$' . "\t\t\t\t\t";
    $line .= "http://localhost/redirect.php?ring=$id";
    $line .= ( $x >= 1 ) ? '&link=$1' : '';
    $line .= ( $x > 1 ) ? '&tag' . ( $x - 1 ) . '=$' . $x . ' [NC]' . "\n" : "\n";
    $lines[] = $line;
}

foreach( $lines as $line )
    echo $line;
+3  A: 

Windows doesn't always understand "\n". Windows uses "\r\n" as default for line breaks.

nicholaides
A: 

Try putting "\r\n" instead of "\n"

Linux: \n
Mac: \r
Win: \n\r
Darin Dimitrov
To be more precise: Mac OS 9: `\r`, Mac OS X: `\n`.
Gumbo
A: 

They work for me. Are you developing on a windows machine? If so you might want to use \r\n or better yet, the PHP_EOL constant which is environment-agnostic.

Mike B
A: 

Are you testing on a windows system or a unix system? I seem to remember that unix systems use different line ending characters in text files than windows systems do.

Wikipedia suggests

"Another common problem is the use of '\n' when communicating using an Internet protocol that mandates the use of ASCII CR+LF for ending lines. Writing '\n' to a text mode stream works correctly on Windows systems, but produces only LF on Unix, and something completely different on more exotic systems. Using "\r\n" in binary mode is slightly better, as it works on many ASCII-compatible systems, but still fails in the general case. One approach is to use binary mode and specify the numeric values of the control sequence directly, "\x0D\x0A"."

http://en.wikipedia.org/wiki/Newline

John Fiala
I'm testing it on a windows machine. However, I'm using XAMPP to run a virtual Apache server on my computer to do my testing. I dunno if that'll make a difference or not.
TJ Kirchner
A: 

Right now I am a bit puzzled about these two headers:

Content-Type: application/octet-stream
Content-Transfer-Encoding: binary

In general, octet-stream is used for binary executables. As the contents is plain text, I also do not see any sense in setting the encoding to "binary".

It is safe to use \r\n for the line break as it works on both UNIX-derviates as well as Microsoft Windows machines.

As for the content type, I would recommend in your case "text/plain".