这里是文章模块栏目内容页
如何让Nextcloud云盘修改代码后能运行在Windows平台的Apache+PHP环境

如何让Nextcloud云盘修改代码后能运行在Windows平台的Apache+PHP环境


Nextcloud私有云盘开源系统越来越受到欢迎,它支持PC端的web管理,支持ios和android以及PC桌面应用连接到系统服务器端,

多平台接入,文件共享和分享移动端和PC端无障碍。可以说是一款优秀的开源软件系统。


Nextcloud云盘的搭建也很简单,在linux平台,通过配置nginx和php-fpm 加mysql 即可运行。整个系统需要的硬件资源可以根据

具体用户量来配置。比如搭建一个公司办公数据共享的云盘环境,用一台普通电脑即可胜任硬件。1核2G内存的云服务器也能运行的不错。


这么好的软件,它居然不支持windows环境上部署服务器端了,这让不少想在windows办公电脑上搭建Nextcloud私有云盘系统的网友大呼不爽,

其实有人尝试了修改了Nextcloud的php代码,能正常部署到windows环境的apache+php+mysql上。命令行部分功能因为需要系权限级别的东西太多

php在windows上缺少一些在linux环境上的库,因此唯一缺憾是少了命令行部分的功能。但是这又有什么关系,windows用户就不习惯命令行。


这里来讲解一下思路。Nextcloud云盘的核心是文件的Webdav服务器。它用了第三方Sbare这个Webdav库,在官方查找到资料,Sbare是支持各种平台环境的。

所以,Nextcloud云盘的核心功能肯定不需要过多修改就能在windows环境上运行。


linux平台与windows平台的PHP,执行起来最大区别就是 路径的 \杠和 /杠的区别。所以他们肯定是修改的重点地方。


所以想先在windows上搭建好apache+php+mysql环境,慢慢调试看看错误发生在哪里。

首先一运行,发现大量的类文件没法autoload,于是去看lib\autoload.php文件 ,找到里面有个方法,对类文件路径进行了检测:

修改 lib/autoloader.php

protected function isValidPath(string $fullPath): bool {
                $fullPath = str_replace("\\", "/", $fullPath);
  foreach ($this->validRoots as $root => $true) {
                        
   if (substr($fullPath, 0, strlen($root) + 1) === $root . '/') {
    return true;
   }
  }
  throw new AutoloadNotAllowedException($fullPath);
 }

==================================================================

上面对 $fullPath 的路径做一下正反斜杠 替换。


然后还有个linux和windows环境上 php的不同,导致在windows平台没法获取到文件的filename数据。

原来是 basename()函数在捣鬼,它在windows平台如果参数是个 文件夹路径,它是没办法返回最后一个文件夹名的,

然而在linux平台,它能返回最后一个文件夹名。然后看看Sbare库对这个函数的优化,里面找到了它的优化代码。

function basenameSplit($path){   
    $matches = [];
    if (preg_match('/^(?:(?:(.*)(?:\/+))?([^\/]+))(?:\/?)$/u', trim($path), $matches)) {
        return [$matches[1], $matches[2]];
    }
    return [null,null];
 
}

用这个函数来代替 basename() 函数的功能;例如

修改lib/private/files/cache/scanner.php

 public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = null, $lock = true) {
  if ($file !== '') {
   try {
                            list(, $fileName) = basenameSplit(trim($file));
    $this->storage->verifyPath(dirname($file),  ($fileName));
   } catch (\Exception $e) {
    return null;
   }
  }

上面代码用basenameSplit来 替换原来的 basename ,它是获取路径里面的filename 的,

好了,按照这个思路,修改几处代码后,windows平台也能正常运行起来了。


本文内容全部完毕,感谢您的阅读,希望能对您有所帮助!