问题 - 我尝试访问应用程序时出现 404 - 文件未找到(包括第一次)
当尝试通过 nextcloud.example.com 在浏览器上访问该应用程序时,我从 NextCloud FMP Docker 容器的控制台日志中收到此错误:
172.19.0.5 - 04/Mar/2023:22:36:01 +0000 "GET /index.php" 404
NGinX Docker 容器的控制台日志中出现以下错误:
172.69.67.108 - - [04/Mar/2023:22:36:01 +0000] "GET / HTTP/2.0" 404 36 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36" "xxx.my.ip.xxx"
Docker 服务器主机和容器的设置
Docker 主机服务器操作系统是 Ubuntu 22.04 LTS
NGinX Docker 容器,我知道 docker-compose.yml 是最好的,但是现在,直到我让它正常工作,我正在使用以下命令运行容器:
docker run -p 80:80 -p 443:443 --name nginx \ --restart=unless-stopped \ -v certbot:/etc/letsencrypt \ -v nginx:/etc/nginx/conf.d \ -v www:/usr/share/nginx/html \ --network tools \ -d nginx
这是 Docker 服务器主机上唯一一个暴露端口的容器,并使用卷挂载来共享:
- 具有 CertBot 容器的证书
- NGinX Conf 目录为每个应用程序设置一个 conf
- HTML www root home 与 NextCloud FPM Docker 容器共享
- 网络工具
NextCloud FPM Docker 容器,我正在使用以下命令运行该容器:
docker run --name nextcloud-fpm \ --restart=unless-stopped \ -v www:/var/www/html \ -e 'TRUSTED_PROXIES=nginx' \ -e 'POSTGRES_HOST=database.server.com' \ -e 'POSTGRES_USER=database_user' \ -e 'POSTGRES_PASSWORD=database_user_password' \ -e 'POSTGRES_DB=databse_name' \ --network tools \ -d nextcloud:fpm
此容器在相同的网络工具上运行,不必将应用程序的端口暴露给 Docker 主机服务器,并且在创建容器堆栈和 NGinX conf 文件时,通过使用容器名称而不是 IP 进行代理反向连接,可以更轻松地完成此操作
- HTML www root home 与 NGinX Docker 容器共享
- 受信任代理(NGinX 容器)的环境变量
- PostgreSQL 数据库的环境变量
- 该容器在 9000 端口上运行 FPM
- 网络工具
NGinX conf 文件,共有 2 个,一个 default.conf,主要不允许直接通过 IP 和端口访问主机服务器(例如 xxx.xxx.xxx.xxx:80 或 xxx.xxx.xxx.xxx:443):
server { # Removes Web Server Info server_tokens off; # HTTP listen 80 default_server; listen [::]:80 default_server; listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; ssl_reject_handshake on; # Identify Server without the name, hence just IP server_name _; # Return Empty Response return 444; }
最后,nextcloud.conf 取自GitHub NextCloud FPM 官方 Repo:
upstream php-handler { server nextcloud-fpm:9000; # In here I set up the Stream with the NextCloud FPM Container name } server { listen 80; listen [::]:80; server_name nextcloud.example.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl; listen [::]:443 ssl; server_name nextcloud.example.com; ssl_certificate /etc/letsencrypt/live/nextcloud.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/nextcloud.example.com/privkey.pem; # HSTS settings # WARNING: Only add the preload option once you read about # the consequences in https://hstspreload.org/. This option # will add the domain to a hardcoded list that is shipped # in all major browsers and getting removed from this list # could take several months. #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always; # set max upload size client_max_body_size 512M; fastcgi_buffers 64 4K; # Enable gzip but do not remove ETag headers gzip on; gzip_vary on; gzip_comp_level 4; gzip_min_length 256; gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/> # Pagespeed is not supported by Nextcloud, so if your server is built # with the `ngx_pagespeed` module, uncomment this line to disable it. #pagespeed off; # HTTP response headers borrowed from Nextcloud `.htaccess` add_header Referrer-Policy "no-referrer" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Download-Options "noopen" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Permitted-Cross-Domain-Policies "none" always; add_header X-Robots-Tag "none" always; add_header X-XSS-Protection "1; mode=block" always; # Remove X-Powered-By, which is an information leak fastcgi_hide_header X-Powered-By; # Path to the root of your installation root /usr/share/nginx/html/; # Since NGinX is the Web Server, I am pointing root to where the NextCloud Files are mounted inside the NGinX Container from the NextCloud FPM Container # Specify how to handle directories -- specifying `/index.php$request_uri` # here as the fallback means that Nginx always exhibits the desired behaviour # when a client requests a path that corresponds to a directory that exists # on the server. In particular, if that directory contains an index.php file, # that file is correctly served; if it doesn't, then the request is passed to # the front-end controller. This consistent behaviour means that we don't need # to specify custom rules for certain paths (e.g. images and other assets, # `/updater`, `/ocm-provider`, `/ocs-provider`), and thus # `try_files $uri $uri/ /index.php$request_uri` # always provides the desired behaviour. index index.php index.html /index.php$request_uri; # Rule borrowed from `.htaccess` to handle Microsoft DAV clients location = / { if ( $http_user_agent ~ ^DavClnt ) { return 302 /remote.php/webdav/$is_args$args; } } location = /robots.txt { allow all; log_not_found off; access_log off; } # Make a regex exception for `/.well-known` so that clients can still # access it despite the existence of the regex rule # `location ~ /(\.|autotest|...)` which would otherwise handle requests # for `/.well-known`. location ^~ /.well-known { # The rules in this block are an adaptation of the rules # in `.htaccess` that concern `/.well-known`. location = /.well-known/carddav { return 301 /remote.php/dav/; } location = /.well-known/caldav { return 301 /remote.php/dav/; } location /.well-known/acme-challenge { try_files $uri $uri/ =404; } location /.well-known/pki-validation { try_files $uri $uri/ =404; } # Let Nextcloud's API for `/.well-known` URIs handle all other # requests by passing them to the front-end controller. return 301 /index.php$request_uri; } # Rules borrowed from `.htaccess` to hide certain paths from clients location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; } location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; } # Ensure this block, which passes PHP files to the PHP process, is above the blocks # which handle static assets (as seen below). If this block is not declared first, # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php` # to the URI, resulting in a HTTP 500 error response. location ~ \.php(?:$|/) { # Required for legacy support rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri; fastcgi_split_path_info ^(.+?\.php)(/.*)$; set $path_info $fastcgi_path_info; try_files $fastcgi_script_name =404; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $path_info; #fastcgi_param HTTPS on; fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice fastcgi_param front_controller_active true; # Enable pretty urls fastcgi_pass php-handler; fastcgi_intercept_errors on; fastcgi_request_buffering off; } location ~ \.(?:css|js|svg|gif)$ { try_files $uri /index.php$request_uri; expires 6M; # Cache-Control policy borrowed from `.htaccess` access_log off; # Optional: Don't log access to assets } location ~ \.woff2?$ { try_files $uri /index.php$request_uri; expires 7d; # Cache-Control policy borrowed from `.htaccess` access_log off; # Optional: Don't log access to assets } # Rule borrowed from `.htaccess` location /remote { return 301 /remote.php$request_uri; } location / { try_files $uri $uri/ /index.php$request_uri; } }
到目前为止我尝试过
我的第一反应是检查日志,我在本文开头分享了它们,然后我去检查文件是否存在于两个容器中,我通过两种不同的方式进行了检查:
我有一个 Portainer 容器在同一个 Docker 主机服务器上运行,并且也在合理的 NGinX Docker 容器后面作为代理反向运行,我连接了一个控制台并查找两个容器内的文件,也在
docker exec container_name -it bash
两个容器上执行了以下操作:NGinX 容器,记住坐骑在
/usr/share/nginx/html
root@61564cff4e67:/# ls -lha /usr/share/nginx/html total 180K drwxrwxrwx 15 www-data www-data 4.0K Mar 4 13:24 . drwxr-xr-x 3 root root 4.0K Feb 9 04:36 .. -rw-r--r-- 1 www-data www-data 3.2K Mar 4 13:24 .htaccess -rw-r--r-- 1 www-data www-data 101 Mar 4 13:24 .user.ini drwxr-xr-x 47 www-data www-data 4.0K Mar 4 13:24 3rdparty -rw-r--r-- 1 www-data www-data 19K Mar 4 13:24 AUTHORS -rw-r--r-- 1 www-data www-data 34K Mar 4 13:24 COPYING drwxr-xr-x 50 www-data www-data 4.0K Mar 4 13:24 apps drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 config -rw-r--r-- 1 www-data www-data 4.0K Mar 4 13:24 console.php drwxr-xr-x 23 www-data www-data 4.0K Mar 4 13:24 core -rw-r--r-- 1 www-data www-data 6.2K Mar 4 13:24 cron.php drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 custom_apps drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 data drwxr-xr-x 2 www-data www-data 12K Mar 4 13:24 dist -rw-r--r-- 1 www-data www-data 156 Mar 4 13:24 index.html -rw-r--r-- 1 www-data www-data 3.4K Mar 4 13:24 index.php drwxr-xr-x 6 www-data www-data 4.0K Mar 4 13:24 lib -rwxr-xr-x 1 www-data www-data 283 Mar 4 13:24 occ drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 ocm-provider drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 ocs drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 ocs-provider -rw-r--r-- 1 www-data www-data 3.1K Mar 4 13:24 public.php -rw-r--r-- 1 www-data www-data 5.5K Mar 4 13:24 remote.php drwxr-xr-x 4 www-data www-data 4.0K Mar 4 13:24 resources -rw-r--r-- 1 www-data www-data 26 Mar 4 13:24 robots.txt -rw-r--r-- 1 www-data www-data 2.4K Mar 4 13:24 status.php drwxr-xr-x 3 www-data www-data 4.0K Mar 4 13:24 themes -rw-r--r-- 1 www-data www-data 383 Mar 4 13:24 version.php
NextCloud FPM 容器,记住坐骑在
/var/www/html
root@938c95d0e1ae:/var/www/html# ls -lha total 180K drwxrwxrwx 15 www-data www-data 4.0K Mar 4 13:24 . drwxrwxr-x 1 www-data root 4.0K Feb 16 03:06 .. -rw-r--r-- 1 www-data www-data 3.2K Mar 4 13:24 .htaccess -rw-r--r-- 1 www-data www-data 101 Mar 4 13:24 .user.ini drwxr-xr-x 47 www-data www-data 4.0K Mar 4 13:24 3rdparty -rw-r--r-- 1 www-data www-data 19K Mar 4 13:24 AUTHORS -rw-r--r-- 1 www-data www-data 34K Mar 4 13:24 COPYING drwxr-xr-x 50 www-data www-data 4.0K Mar 4 13:24 apps drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 config -rw-r--r-- 1 www-data www-data 4.0K Mar 4 13:24 console.php drwxr-xr-x 23 www-data www-data 4.0K Mar 4 13:24 core -rw-r--r-- 1 www-data www-data 6.2K Mar 4 13:24 cron.php drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 custom_apps drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 data drwxr-xr-x 2 www-data www-data 12K Mar 4 13:24 dist -rw-r--r-- 1 www-data www-data 156 Mar 4 13:24 index.html -rw-r--r-- 1 www-data www-data 3.4K Mar 4 13:24 index.php drwxr-xr-x 6 www-data www-data 4.0K Mar 4 13:24 lib -rwxr-xr-x 1 www-data www-data 283 Mar 4 13:24 occ drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 ocm-provider drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 ocs drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 ocs-provider -rw-r--r-- 1 www-data www-data 3.1K Mar 4 13:24 public.php -rw-r--r-- 1 www-data www-data 5.5K Mar 4 13:24 remote.php drwxr-xr-x 4 www-data www-data 4.0K Mar 4 13:24 resources -rw-r--r-- 1 www-data www-data 26 Mar 4 13:24 robots.txt -rw-r--r-- 1 www-data www-data 2.4K Mar 4 13:24 status.php drwxr-xr-x 3 www-data www-data 4.0K Mar 4 13:24 themes -rw-r--r-- 1 www-data www-data 383 Mar 4 13:24 version.php
Docker 服务器主机绑定挂载最后检查 Docker 主机服务器本身的文件,因为我不仅想实现两个容器的根位置共享,而且如果需要移动容器,还想拥有持久数据:
❯ ll total 180K drwxrwxrwx 15 www-data www-data 4.0K Mar 4 13:24 . drwxrwxr-x 10 Alejandro Alejandro 4.0K Mar 4 13:24 .. drwxr-xr-x 47 www-data www-data 4.0K Mar 4 13:24 3rdparty drwxr-xr-x 50 www-data www-data 4.0K Mar 4 13:24 apps -rw-r--r-- 1 www-data www-data 19K Mar 4 13:24 AUTHORS drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 config -rw-r--r-- 1 www-data www-data 4.0K Mar 4 13:24 console.php -rw-r--r-- 1 www-data www-data 34K Mar 4 13:24 COPYING drwxr-xr-x 23 www-data www-data 4.0K Mar 4 13:24 core -rw-r--r-- 1 www-data www-data 6.2K Mar 4 13:24 cron.php drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 custom_apps drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 data drwxr-xr-x 2 www-data www-data 12K Mar 4 13:24 dist -rw-r--r-- 1 www-data www-data 3.2K Mar 4 13:24 .htaccess -rw-r--r-- 1 www-data www-data 156 Mar 4 13:24 index.html -rw-r--r-- 1 www-data www-data 3.4K Mar 4 13:24 index.php drwxr-xr-x 6 www-data www-data 4.0K Mar 4 13:24 lib -rwxr-xr-x 1 www-data www-data 283 Mar 4 13:24 occ drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 ocm-provider drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 ocs drwxr-xr-x 2 www-data www-data 4.0K Mar 4 13:24 ocs-provider -rw-r--r-- 1 www-data www-data 3.1K Mar 4 13:24 public.php -rw-r--r-- 1 www-data www-data 5.5K Mar 4 13:24 remote.php drwxr-xr-x 4 www-data www-data 4.0K Mar 4 13:24 resources -rw-r--r-- 1 www-data www-data 26 Mar 4 13:24 robots.txt -rw-r--r-- 1 www-data www-data 2.4K Mar 4 13:24 status.php drwxr-xr-x 3 www-data www-data 4.0K Mar 4 13:24 themes -rw-r--r-- 1 www-data www-data 101 Mar 4 13:24 .user.ini -rw-r--r-- 1 www-data www-data 383 Mar 4 13:24 version.php root@myserver /mnt/Volume/data/www
我看不出为什么从权限角度来说它无法工作,并且已确认文件在所有三个实例中都存在。
检查 NGinX conf 文件中的 NextCloud FPM nextcloud.conf,经过深思熟虑后,我认为唯一可能出错的地方是,因为我通过浏览器上的域一直访问到 NGniX Web 服务器容器,因为我在其日志中有 404 Not Found 条目,而且我还从 NextCloud 容器实例本身获得了一个 404 Not Found 的响应,我遇到的唯一问题与 conf 文件上的根条目有关:
NextCloud 日志:
172.19.0.5 - 04/Mar/2023:22:36:01 +0000 "GET /index.php" 404
NGinX 日志:
172.69.67.108 - - [04/Mar/2023:22:36:01 +0000] "GET / HTTP/2.0" 404 36 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36" "xxx.my.ip.xxx"
因此我将根指令改为
/var/www/html
,行为略有改变,我仍然收到 404 Not Found 条目,但仅限于 NGinX Web 服务器容器日志,NextCloud 容器处于静默状态,因此我无法通过此更改达到它的目的:NextCloud 日志(空,没有任何条目):
NGinX 日志:
2023/03/05 00:13:24 [error] 473#473: *4152 "/var/www/html/index.php" is not found (2: No such file or directory), client: 172.69.65.73, server: nextcloud.example.com, request: "GET / HTTP/2.0", host: "nextcloud.example.com" 172.69.65.73 - - [05/Mar/2023:00:13:24 +0000] "GET / HTTP/2.0" 404 174 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36" "xxx.my.ip.xxx"
Web 服务器的行为方式有所不同,我注意到在 root 指令更改之后,我在日志中看到引号之间的实际域,
"nextcloud.example.com"
而之前只是一个破折号"-"
。下一步就是禁用 NGinX conf 文件中的 default.conf,因为这是我能想到的唯一地方
"-"
,结果与上面相同,我重复了已经尝试过的场景 1 和 2,它"_"
也是 default.conf 的服务器指令,所以是盲目的尝试。我已尝试过 conf 的许多其他设置,但大多数最终都变成了
Too Many Redirections
、Bad Certificate
或者只是简单的502
错误。
我确定问题是什么以及我被困在哪里
看来我已经非常接近我想要的结果了,因为我可以通过具有所需域的浏览器访问两个容器,而且 SSL 也能很好地解析,但是,服务器名称似乎没有被 NGinX conf 文件捕获,然后没有正确传递给 NextCloud,但我不知道到底要改什么。
因为我认为我已经将其范围缩小到我认为的具体问题,也许有人可以帮助我检查 NGinX conf 文件 nextcloud.conf 并指出哪里设置错误。
感谢您阅读这篇长文。
答案1
我找到了答案,因此我将提供详细的信息来帮助已经遇到同样问题的人以及将来可能遇到此问题的人,考虑到我发现了多少没有答案的问题和问题。
问题在于 NGinX conf 文件的 FastCGI 参数中的 FPM 根位置
所以我走在正确的轨道上,问题与根指令有关。
读了很多书之后,我偶然发现了这篇文章:
突然间我意识到我有两个不同的服务读取两个不同的路径,其中一个正在为另一个不存在的根路径提供信息。
还记得我已经安装了要在两个容器之间共享的 www 卷吗?
- 对于 NGinX 容器
www:/usr/share/nginx/html
- 对于 NextCloud FPM 容器
www:/var/html/www
其背后的想法是让两个容器共享 NextCloud 应用程序的文件系统。
我没有意识到的是,在这个部署中,NGinX 的目的是提供静态文件,如 CSS、HTML、JPG、JS 等,同时使用 FastCGI 参数将 PHP 调用路由到 NextCloud FPM 容器。
当 NGinX conf 文件中的根指令被声明时,它会被设置为变量$document_root
。
root /usr/share/nginx/html;
因此,当将根设置为 NGinX 容器上的路径时,/usr/share/nginx/html
这可以毫无问题地提供静态文件,但是,当进行 PHP 调用时,它会被提供给 NextCloud FPM 容器中的 php-hanlder,由于该位置在第二个容器内不存在,所以它找不到 PHP 文件。
为了解决这个问题,我使用 FastCGI 参数搜索了块并搜索了$document_root
变量,找到了它,如下所示:
location ~ \.php(?:$|/) {
# Required for legacy support
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
#fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
fastcgi_param front_controller_active true; # Enable pretty urls
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
请注意,该行是如何fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
使用已经声明的根来形成脚本路径的,因此在处理时nextcloud.example.com
它会尝试读取index.php
,这是对 NextCloud FPM 容器的结果调用:
/usr/share/nginx/html/index.php
正确的做法应该是:
/var/www/html/index.php
因此我创建了一个名为的新变量$fpm_root
并将其设置为/var/www/html/
,然后将该行更改fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
为fastcgi_param SCRIPT_FILENAME $fpm_root$fastcgi_script_name;
现在,每当它收到静态内容调用时,它都会解析 NGinX 的容器路径,当它收到 PHP 内容调用时,它就会解析 NextCloud FPM 的容器路径。
整个部分现在的样子如下:
location ~ \.php(?:$|/) {
# Required for legacy support
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
set $fpm_root /var/www/html/;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $fpm_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
fastcgi_param front_controller_active true; # Enable pretty urls
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
一旦我添加了以下行,它现在就可以正常工作并通过所有内部 NextCloud 健康和安全检查:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
结论
我希望这可以帮助任何搜索此问题的人,问题是我为处理两种类型内容(静态和 PHP)的服务提供了两条不同的路径,并且只有其中一个在 NGinX conf 文件中正确设置。
您可以为 dockerized FPM 部署拥有两个不同的(或更多)根位置,这可能可以工作或将静态内容部署到两个或更多不同的应用程序中,使用相同的 FPM 容器来处理 NextCloud、WordPress、PHPPGAdmin、Laravel 或您正在处理的任何内容的 PHP 调用。