Skip to content


PHPExcel在php5.2.10上的bug

Fatal error: Class ‘PHPExcel_Worksheet’ not found in /htdocs/webapp/includes/libs/PHPExcel.php on line 114

PHPExcel.php第114行内容

  1. $this->_workSheetCollection[] = new PHPExcel_Worksheet($this);

PHPExcel使用了自动载入class
PHPExcel/Autoloader.php 第43行输入调试代码

  1. echo $pObjectFilePath;
  2. var_dump(file_exists($pObjectFilePath));
  3. echo "<br>";
  4.  
  5. if ((file_exists($pObjectFilePath) === false) || (is_readable($pObjectFilePath) === false)) {
  6. return false;
  7. }
  1. /htdocs/webapp/includes/libs/PHPExcel/Shared/ZipStreamWrapper.phpbool(true)
  2. /htdocs/webapp/includes/libs/PHPExcel/Worksheet.phpbool(false)
  3.  
  4. Fatal error: Class 'PHPExcel_Worksheet' not found in /htdocs/webapp/includes/libs/PHPExcel.php on line 114

Worksheet.php文件没有存在?
反复检查了php中open_basedir,文件及目录权限,zip扩展,pear都没问题.
并在autoloader前用代码测试文件确实可以检测到.

  1. var_dump(file_exists('/htdocs/webapp/includes/libs/PHPExcel/Worksheet.php'));

试了下把ZipStreamWrapper.php禁止载入后就可顺利通过.
注释PHPExcel.php第34行内容

  1. PHPExcel_Autoloader::Register();
  2. //PHPExcel_Shared_ZipStreamWrapper::register();

看来问题确实在这里,再用代码确认下是stream_register_wrapper和file_exists的bug

  1. class VariableStream {
  2.     var $position;
  3.     var $varname;
  4.   
  5.     function stream_open($path, $mode, $options, &$opened_path)
  6.     {
  7.         $url = parse_url($path);
  8.         $this->varname = $url["host"];
  9.         $this->position = 0;
  10.         
  11.         return true;
  12.     }
  13.  
  14.     function stream_read($count)
  15.     {
  16.         $ret = substr($GLOBALS[$this->varname], $this->position, $count);
  17.         $this->position += strlen($ret);
  18.         return $ret;
  19.     }
  20.  
  21.     function stream_write($data)
  22.     {
  23.         $left = substr($GLOBALS[$this->varname], 0, $this->position);
  24.         $right = substr($GLOBALS[$this->varname], $this->position + strlen($data));
  25.         $GLOBALS[$this->varname] = $left . $data . $right;
  26.         $this->position += strlen($data);
  27.         return strlen($data);
  28.     }
  29.  
  30.     function stream_tell()
  31.     {
  32.         return $this->position;
  33.     }
  34.  
  35.     function stream_eof()
  36.     {
  37.         return $this->position >= strlen($GLOBALS[$this->varname]);
  38.     }
  39.  
  40.     function stream_seek($offset, $whence)
  41.     {
  42.         switch($whence) {
  43.             case SEEK_SET:
  44.                 if ($offset < strlen($GLOBALS[$this->varname]) && $offset >= 0) {
  45.                      $this->position = $offset;
  46.                      return true;
  47.                 } else {
  48.                      return false;
  49.                 }
  50.                 break;
  51.                 
  52.             case SEEK_CUR:
  53.                 if ($offset >= 0) {
  54.                      $this->position += $offset;
  55.                      return true;
  56.                 } else {
  57.                      return false;
  58.                 }
  59.                 break;
  60.                 
  61.             case SEEK_END:
  62.                 if (strlen($GLOBALS[$this->varname]) + $offset >= 0) {
  63.                      $this->position = strlen($GLOBALS[$this->varname]) + $offset;
  64.                      return true;
  65.                 } else {
  66.                      return false;
  67.                 }
  68.                 break;
  69.                 
  70.             default:
  71.                 return false;
  72.         }
  73.     }
  74. }
  75.  
  76. var_dump(file_exists('/htdocs/webapp/includes/libs/PHPExcel.php'));
  77.  
  78. stream_register_wrapper("var", "VariableStream")
  79.     or die("Failed to register protocol");
  80. var_dump(file_exists('/htdocs/webapp/includes/libs/PHPExcel.php'));

输出结果

  1. bool(true) bool(false)

解决方法:
1.注释PHPExcel.php第34行内容
PHPExcel_Shared_ZipStreamWrapper::register();

2.更换php版本
目前换成php.5.2.14没有问题

Posted in PHP, 技术.

Tagged with , .


No Responses (yet)

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.



Some HTML is OK

or, reply to this post via trackback.