CHttpRequest 在Nginx下使用xSendFile bug

今天在做一个文件下载时, 在Nginx下面使用文件下载性能X-Accel-Redirect 提升下载文件下载性能, 使用CHttpRequest xSendFile方法, 始终返回空白.

根据Nginx 官方文档说明, http://wiki.nginx.org/XSendfile , 必须使用internal作为内部使用,alias标识文件存储的真实路径,

location /filedown/ {

internal;

alias /some/path/; # note the trailing slash

}

在Yii应用程序中我们必须使用/filedown/ 来获得下载目录+文件名称Nginx才能正常解析,类似下面的代码.





  		Yii::app()->request->xSendFile('/filedown/test.zip',array(

              'saveName'=>$filename,

       		'mimeType'=>'application/octet-stream',  			

   			'xHeader'=>'X-Accel-Redirect',  			

   			'terminate'=>false,

   		));




而翻开CHttpRequest -> xSendfile 方法源码可以看到头一行检测文件存在代码将永远返回false,直接返回空白。





public function xSendFile($filePath, $options=array())

	{

		if(!is_file($filePath))   //在Ningx下面,这行代码不需要检测,永远为false,因为Nginx内部通过别名来获取真实路径.

			return false;

  	

	}




目前有遇到这个问题的朋友,可以直接使用解决.





header('Content-type: '.$options['mimeType']);

		header('Content-Disposition: attachment; filename="'.$options['saveName'].'"');

		header('X-Accel-Redirect: '.$filePath);




像文件下载这种功能 从来都只用绝对路径 配合 pathAlias 不会出啥问题吧:

xSendFile(Yii::getPathOfAlias(‘application.filedown’).DIRECTOR_SEPERATOR.‘test.zip’,array(

          'saveName'=>$filename,


            'mimeType'=>'application/octet-stream',                         


                    'xHeader'=>'X-Accel-Redirect',                          


                    'terminate'=>false,


            ));

这个/filedown/是nginx配置文件里面定义的,不是由Yii解析, 查看CHttpRequest -> xSendfile 方法源代码可以看到这一行,实际是交由Web服务器处理这个路径,而Nginx必须配置

location /filedown/ {

internal;

alias /some/path/;

}

使用internal 标记为只有nginx内部使用,才可以正常使用X-Accel-Redirect协议, X-Accel-Redirect本身不是一个标准协议,每个Web服务器使用都不同。





public function xSendFile($filePath, $options=array())

   {


header(trim($options['xHeader']).': '.$filePath);


}




上面这一行实际等于:

header(‘X-Accel-Redirect : /filedown/test.zip’);

Yii和PHP不做任何事情,全部交给Nginx来处理, 查看Nginx配置说明:

http://wiki.nginx.org/XSendfile

相关性能文章介绍:

http://www.iteye.com/topic/154538

http://www.yiiframew…b-applications/

嗯 是这样的 :lol:

学习了