XSym 符号链接不能用于 PHP on Docker for Windows
XSym symbolic links cannot be used in PHP on Docker for Windows
当在 Windows 上的 Docker 容器内使用 PHP 时(例如使用 DDEV),在容器内创建的符号 links(例如由 composer) 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"
}
在主机系统中查看符号 link 时(例如在 Windows PowerShell 中使用 cat demo-symbolic-link
)它显示
XSym
0019
0df68e8650ddca993c28277a5cfa3dcd
demo-base-directory
关于 Windows 的 Docker 关于 symlink 仿真的其他报告 - 我无法使用 fgets
或 [=26= 为文件重现此行为] 但对于提到的 glob
调用,请参阅
共享卷安装在 Windows 主机系统上基于 Linux 的 Docker 容器中,如下所示 Samba/CIFS 安装:
//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
解决方法
不是在容器内创建符号 link,而是在 外部 (直接在 Windows 中)创建它们解决了问题。
使用普通 mklink in cmd.exe
del demo-symbolic-link
mklink /d demo-symbolic-link demo-base-directory
输出
symbolic link created for demo-symbolic-link <<===>> demo-base-directory
在 PowerShell 中通过 cmd 使用普通 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 in PHP
解决 - 此处也使用 mklink /d
对 Windows
使用 Git-Bash
我必须在以管理员身份执行 Git-Bash 时执行以下命令。使用 export
设置环境变量在这里很重要 - 请参阅 Enable native NTFS symbolic links for Cygwin
rm demo-symbolic-link
export MSYS=winsymlinks:nativestrict
ln -s demo-base-directory/ demo-symbolic-link
辅助工具
我创建了帮助工具示例,用于在特定目录中搜索 Samba XSym
指针(与 TYPO3 相关,public/typo3conf/ext/
)和 "upgrade" XSym 指向正确符号的指针links - 执行这些脚本时可能需要管理员权限:
结果
再次执行上面的 PHP 示例现在会输出两个预期项目
array(2) {
[0]=>
string(19) "demo-base-directory"
[1]=>
string(18) "demo-symbolic-link"
}
问题
在 Docker 容器内工作并且必须在主机系统上手动调整符号 links 实际上只是一种解决方法 - 而不是解决方案。为了仅使用 Docker 容器创建适当的符号 link,可以在哪个级别对其进行增强和优化?
这似乎可以在不同的层次上解决:
- PHP's
glob
invocation(尤其是易碎的 GLOB_ONLYDIR
标志)
- glibc 的
glob
实现(特别是 Minshall+French symlinks XSym
)
- Docker 不使用 Samba/CIFS 进行卷共享
更新
- 从
mklink /j
(连接点)切换到 mklink /d
(symlinked 目录),因为删除 linked 连接点也删除了它的来源
- PowerShell 的 symlink cmdlet
New-Item -ItemType SymbolicLink
(而不是之前的 New-Item -ItemType Junction
)然后再次无法使用 PHP 中的 glob(..., GLOB_ONLYDIR
解析 - 结果, 这里使用 cmd /c mklink /d
- 添加了Samba/CIFS挂载信息
从 ddev v1.5.0 开始,Windows 上的 ddev composer
命令尝试将 XSym 符号链接转换为合法的 Windows 符号链接。此功能仅在您在 Windows 上启用 "Developer mode" 时有效。请参阅文档中的 Windows OS and ddev composer。
当在 Windows 上的 Docker 容器内使用 PHP 时(例如使用 DDEV),在容器内创建的符号 links(例如由 composer) 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"
}
在主机系统中查看符号 link 时(例如在 Windows PowerShell 中使用 cat demo-symbolic-link
)它显示
XSym
0019
0df68e8650ddca993c28277a5cfa3dcd
demo-base-directory
关于 Windows 的 Docker 关于 symlink 仿真的其他报告 - 我无法使用 fgets
或 [=26= 为文件重现此行为] 但对于提到的 glob
调用,请参阅
共享卷安装在 Windows 主机系统上基于 Linux 的 Docker 容器中,如下所示 Samba/CIFS 安装:
//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
解决方法
不是在容器内创建符号 link,而是在 外部 (直接在 Windows 中)创建它们解决了问题。
使用普通 mklink in cmd.exe
del demo-symbolic-link
mklink /d demo-symbolic-link demo-base-directory
输出
symbolic link created for demo-symbolic-link <<===>> demo-base-directory
在 PowerShell 中通过 cmd 使用普通 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 in PHP
解决 - 此处也使用 mklink /d
对 Windows
使用 Git-Bash我必须在以管理员身份执行 Git-Bash 时执行以下命令。使用 export
设置环境变量在这里很重要 - 请参阅 Enable native NTFS symbolic links for Cygwin
rm demo-symbolic-link
export MSYS=winsymlinks:nativestrict
ln -s demo-base-directory/ demo-symbolic-link
辅助工具
我创建了帮助工具示例,用于在特定目录中搜索 Samba XSym
指针(与 TYPO3 相关,public/typo3conf/ext/
)和 "upgrade" XSym 指向正确符号的指针links - 执行这些脚本时可能需要管理员权限:
结果
再次执行上面的 PHP 示例现在会输出两个预期项目
array(2) {
[0]=>
string(19) "demo-base-directory"
[1]=>
string(18) "demo-symbolic-link"
}
问题
在 Docker 容器内工作并且必须在主机系统上手动调整符号 links 实际上只是一种解决方法 - 而不是解决方案。为了仅使用 Docker 容器创建适当的符号 link,可以在哪个级别对其进行增强和优化?
这似乎可以在不同的层次上解决:
- PHP's
glob
invocation(尤其是易碎的GLOB_ONLYDIR
标志) - glibc 的
glob
实现(特别是 Minshall+French symlinksXSym
) - Docker 不使用 Samba/CIFS 进行卷共享
更新
- 从
mklink /j
(连接点)切换到mklink /d
(symlinked 目录),因为删除 linked 连接点也删除了它的来源 - PowerShell 的 symlink cmdlet
New-Item -ItemType SymbolicLink
(而不是之前的New-Item -ItemType Junction
)然后再次无法使用 PHP 中的glob(..., GLOB_ONLYDIR
解析 - 结果, 这里使用cmd /c mklink /d
- 添加了Samba/CIFS挂载信息
从 ddev v1.5.0 开始,Windows 上的 ddev composer
命令尝试将 XSym 符号链接转换为合法的 Windows 符号链接。此功能仅在您在 Windows 上启用 "Developer mode" 时有效。请参阅文档中的 Windows OS and ddev composer。