using urlmanager and mvc for download authorization system

I would like to take advantage of the url manager and MVC structure to control download. Basically, I would like to create a download controller such that download_1234 will be mapped to a file under protected/download/1234.pdf

This way, I can take advantage of the authorization system while avoiding the PHP-intensive fread() authorization method.

So is it possible to do so? Can qiang or other capable members shed some light if this is doable?

You can make it as an action, e.g. site/download. In the action, you check the authorization. Then use Yii::app()->request->sendFile() to send the file to client.

For the URL rule, use the following:


Thank you very much Qiang. I didnot know there is a sendFile function. That saves lot of time. I have been scratching my head to port my downloading code to yii.

Just check the function in the guide. I am little bit confused. Can the sendFile function send any file inside the protected folder?

According to doc it looks like it. It will try to determine mimetype auto by looking at file (ext i guess) if you dont specify it yourself that is. Give it a spin and try :)

An example:

sendFile('guide.pdf', file_get_contents('path/to/123.pdf'))

Qiang, after I studied the sendFile function in the CHttpRequest class, I decided to use my own function. For large files (100M+), my functions works better (for me now) . I think the built-in sendFile function would be pretty good for smaller files.

function dl_file($file){






	header(&quot;Content-Type: application/force-download&quot;);

	header(&quot;Content-Type: application/octet-stream&quot;);

	header(&quot;Content-Type: application/download&quot;);

	header(&#039;Content-Disposition: attachment; filename=&quot;&#039;.$dlname.&#039;&quot;&#039;);

	header(&#039;Content-Encoding: none&#039;);

	header(&quot;Accept-Ranges: bytes&quot;);

	header(&#039;Cache-Control: public&#039;);

	header(&quot;Content-Description: File Transfer&quot;);

	header(&quot;Pragma: public&quot;);


	header(&quot;Expires: Mon, 26 Jul 1997 05:00:00 GMT&quot;);

	//header(&quot;Last-Modified: &quot;.gmdate(&quot;D, d M Y H:i:s&quot;).&quot; GMT&quot;);

	header(&quot;Content-Length: &quot;.$content_len);

	header(&quot;Content-Transfer-Encoding: binary&quot;);


	while(!feof($fp)) {

		$buffer=fread($fp, 65536);

		echo $buffer;








Yeah, for such big files, sendFile() is not appropriate since it needs too much memory.