在
Windows上的Docker容器中使用
PHP时(例如使用DDEV),在容器内创建的符号链接(例如,通过编写器)似乎无法正常使用PHP的文件流.
脚本
想象一下下面的PHP代码
<?php
mkdir('demo-base-directory');
symlink('demo-base-directory', 'demo-symbolic-link');
var_dump(glob('demo-*', GLOB_ONLYDIR));
如果在容器内执行,它只输出demo-base-directory,但是缺少demo-symbolic-link(同样的例子在Docker容器内的Linux / Unix系统上按预期工作)
array(1) {
[0]=>
string(19) "demo-base-directory"
}
查看主机系统中的符号链接时(例如,在Windows PowerShell中使用cat demo-symbolic-link),它会显示
XSym
0019
0df68e8650ddca993c28277a5cfa3dcd
demo-base-directory
还有其他关于Docker for Windows的关于符号链接仿真的报告 – 我无法为使用fgets或file_get_contents的文件重现这种行为,但对于提到的glob调用,请参阅
> https://github.com/docker/for-win/issues/137
> https://github.com/drud/ddev/issues/1283
共享卷安装在Windows主机系统上基于Linux的Docker容器中,如下所示:Samba / CIFS mount:
//10.0.75.1/C on /var/www/html type cifs
(rw,relatime,vers=3.02,sec=ntlmsspi,cache=strict,username=olly,domain=OLIVERHADERB9D8,uid=0,noforceuid,gid=0,noforcegid,addr=10.0.75.1,file_mode=0755,dir_mode=0777,iocharset=utf8,nounix,serverino,mapposix,nobrl,mfsymlinks,noperm,rsize=1048576,wsize=1048576,echo_interval=60,actimeo=1)
挂载选项mfsymlinks指的是Minshall+French symlinks
解决方法
而不是在容器内创建符号链接,在外部(直接在Windows中)创建它们可以解决问题.
del demo-symbolic-link
mklink /d demo-symbolic-link demo-base-directory
产量
symbolic link created for demo-symbolic-link <<===>> demo-base-directory
在PowerShell中通过cmd使用plain mklink
del demo-symbolic-link
cmd /c mklink /d demo-symbolic-link demo-base-directory
产量
symbolic link created for demo-symbolic-link <<===>> demo-base-directory
旁注:New-Item -ItemType SymbolicLink无法使用glob(…,GLOB_ONLYDIR在PHP中解析 – 在这里使用mklink / d)
使用Git-Bash for Windows
我以管理员身份执行Git-Bash时必须执行以下操作.在这里设置环境变量很重要 – 见Enable native NTFS symbolic links for Cygwin
rm demo-symbolic-link
export MSYS=winsymlinks:nativestrict
ln -s demo-base-directory/ demo-symbolic-link
帮助工具
我创建了帮助工具示例,在特定目录(TYPO3相关,公共/ typo3conf / ext /)中搜索Samba XSym指针,并将XSym指针“升级”为正确的符号链接 – 执行这些脚本时可能需要管理员权限:
> BAT helper to be used in cmd.exe
> BASH helper to be used in Git-Bash
结果
再次从上面执行PHP示例现在输出两个预期的项目
array(2) {
[0]=>
string(19) "demo-base-directory"
[1]=>
string(18) "demo-symbolic-link"
}
题
在Docker容器内工作并且必须在主机系统上手动调整符号链接实际上只是一种解决方法 – 而不是解决方案.在哪个级别可以增强和优化,以便仅使用Docker容器创建正确的符号链接?
看来这可以在不同的层次解决:
> PHP’s glob
invocation(特别是对于片状GLOB_ONLYDIR标志)
> glibc’s glob
implementation(尤其是Minshall+French symlinks XSym)
> Docker不使用Samba / CIFS进行卷共享
更新
>从mklink / j(交汇点)切换到mklink / d(符号链接目录),因为删除链接的联结也删除了它的来源
> PowerShell的symlink cmdlet New-Item -ItemType SymbolicLink(而不是以前的New-Item -ItemType Junction)然后再次无法使用glob(…,GLOB_ONLYDIR在PHP中解析 – 因此,在这里使用cmd / c mklink / d
>添加了Samba / CIFS装载信息
最佳答案 从ddev v1.5.0开始,Windows上的ddev composer命令尝试将XSym符号链接转换为合法的Windows符号链接.此功能仅在Windows上启用“开发人员模式”时才有效.请参阅docs中的
Windows OS and ddev composer.