Symfony2 : header won’t change in download controller action

Sooner or late you have to add file download option to your symfony2 project. As many times before I have been created controller just for that. It was looking something like this:


/**
  * FileDownload controller
  */
public function returnFileAction($id)
{
    // security check
    if(!is_numeric($id))
    {
    	return new Response('', HTTP_BAD_REQUEST);
    }
       
    // parameters.yml
    $fileDir = $this->container->getParameter('path_to_files');
       
    // find file by name, don't care about extension
    $fileArray = glob($fileDir . "$id.*");
    
    // expecting only one result
    if(count($fileArray) != 1) {
    	return new Response('', HTTP_BAD_REQUEST);	
    }

    $filePath = $fileArray[0];
    
    $finfo = finfo_open(FILEINFO_MIME_TYPE);

    $response = new Response();
    
    // Set headers
    $response->headers->set('Cache-Control', 'private');
    $response->headers->set('Content-type', finfo_file($finfo, $filePath));
    $response->headers->set('Content-Disposition', 'inline; filename="' . basename($filePath) . '";');
    $response->headers->set('Content-length', filesize($filePath));
	
    // Send headers before outputting anything
    $response->sendHeaders();
    
    readfile($filePath);

    return $response;
}

Common mistake is to set readfile before sending header back to user.

Result of sending wrong http header leads to byte output directly to browser interpreted as plain text. In that case move readfile or wrap it with ob_start/ob_end.

Example :


ob_start();
readfile($filePath);
$file = ob_get_contents();
// ...
// at end of function
$response->setContent($file);

Take care to put file output at end and eliminate possible error output it will save you some debugging time, trust me I know ;)

PHP : __FILE__ problem with symolics links

Some time ago I have organized my wordpress plugins via symbolic links. It’s helped me to keep all plugins inside one repository dir and eases me to deploy plugins in different test wordpress locations on my WAMP server. Example of that organization :


d:\plugins\plugin1 // real loaction
d:\plugins\plugin2 // real location
...
d:\www\wordpress\wp-content\plugins\plugin1 // symbolic link
d:\www\wordpress\wp-content\plugins\plugin2 // symbolic link
...

Symbolic links are created by :


mklink /D d:\www\wordpress\wp-content\plugins\plugin1 d:\plugins\plugin1

Everything worked well until I have to use __FILE__ varibale. My agony started when I wonted to create plugin with install callback function :


# d:\www\wordpress\wp-content\plugins\plugin1\main.php
register_activation_hook(__FILE__, array( &$plugin, 'install'));

As you can assume this callback function was never triggered. After a while looking at all the wrong places I finally found the problem.

__FILE__ returns real path not the symbolic!

So, in my example output of __FILE__ was : d:\plugins\plugin1\main.php and wordpress is looking for : d:\www\wordpress\wp-content\plugins\plugin1\main.php

I don’t know how __FILE__ behaves in LAMP environment with symbolic links, this is first thing that I am planing to test.

Note to myself: testing in real test environment is far better than that WAMP solution. (By “real test environment” I meant copy of real ;)

Hello world!

It’s have been a long time since I bought this domain and it’s about time to do something with it. ;)
So this is a new beginning for www.nikolaloncar.com and I hope that you find something helpful in this blog.