使用PHP脚本创建的符号链接没有显示,但它在那里?

gre*_*emo 7 php subdomain hosting shared-hosting symfony

我的Symfony 2安装在共享主机站点上.目录结构:

public
|-- api          // subdomain api.mydomain.com
|-- app
|-- bin
|-- m            // subdomain m.mydomain.com
|-- src
|-- vendor
|-- www          // symfony "web" folder
|    |
|    +-- app.php // front controller!
Run Code Online (Sandbox Code Playgroud)

文件夹www主文件夹,它是前端控制器所在的文件夹.它的界限是mydmain.com或者www.mydomain.com.子域名喜欢m.mydomain.com或是一个api.mydomain.com文件夹public(即mapi).

我没有SSH访问权限,只有FTP(没有SFTP).问题不在于重复www内部mapi文件夹的内容.如果我将所有内容复制wwwapi(比方说)前端控制器正在工作,我可以在Symfony 2中使用子域.

到目前为止我尝试过的:

符号链接解决方案

创建一个apipoiting到www文件夹的符号链接.我已经使用了放在www文件夹中的folling脚本:

<?php

var_dump(__DIR__); // /htdocs/public/www where script is executed

$target = '/htdocs/public/www';
$link = '/htdocs/public/api';

if(file_exists($link)) {
    if(is_link($link)) {
        echo "unlinking $link...";
        var_dump(unlink($link));

        echo "symlinking $link to $target...";
        var_dump(symlink($target, $link));
    } else {
        exit("$link exists but not symbolic link\n");
    }
}

echo readlink($link); // /htdocs/public/www correct!
echo exec('cd .. && ls -l');
Run Code Online (Sandbox Code Playgroud)

输出:

/htdocs/public/www
unlinking /htdocs/public/api... bool(true)
symlinking /htdocs/public/api to /htdocs/public/www... bool(true)
/htdocs/public/www
drwxr-xr-x 7 nobody nobody 4096 Nov 25 18:57 www
Run Code Online (Sandbox Code Playgroud)

创建了符号链接但是(这很奇怪)我无法通过FTP或文件管理器界面(web)看到它的连接.前控制器不起作用.符号链接它在那里,如果我尝试创建一个与符号链接同名的文件夹,我会收到错误.

.htaccess解决方案

如何apiwww文件夹的所有请求路由到文件夹(或从api子域到www子域)?这个解决方案对我来说似乎不太正确(为什么301重定向GET /users api.mydomain.com)?

TMS*_*TMS 5

我有完全相同的配置,并让它工作!唯一的区别是我将api.domain.com映射到www.domain.com/api而不是你的www.domain.com,所以我的api符号链接指向www/api,而不是www.

.htaccess解决方案

您可以使用下面描述的一个不需要符号链接的方案的修改:

/htdocs/public/.htaccess:

首先包括在重定向中保留HTTP/HTTPS协议代码(我将假设所有示例的代码):

RewriteEngine on
RewriteCond %{HTTPS} =on
RewriteRule ^(.*)$ - [env=proto:https]
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ - [env=proto:http]
Run Code Online (Sandbox Code Playgroud)

重定向代码:

RewriteCond %{HTTP_HOST}  ^api\.domain\.com$ [NC]
RewriteRule ^(.*)$        %{ENV:proto}://domain.com/api/$1 [L]
Run Code Online (Sandbox Code Playgroud)

这会将所有请求重定向api.domain.com/$1domain.com/api/$1.或者你可以随意使用http://domain.com/$1.

编辑:如果您不想对域进行硬编码,则可以使用%N反向引用:

# don't forget to use the HTTP/HTTPS handling code above
RewriteCond %{HTTP_HOST}    ^api\.([a-zA-Z0-9-]+\.[a-zA-Z0-9-]+)$ [NC]
RewriteRule ^(.*)$           %{ENV:proto}://%1/api/$1 [L]
Run Code Online (Sandbox Code Playgroud)

符号链接解决方案

I)关于符号链接,很奇怪你没有看到FTP上的符号链接.我在FileZilla中看到它作为一个目录(好像它是一个硬链接).尝试安装FileZilla(并使用显式FTP over TLS进行安全身份验证).

II)Options +FollowSymLinks必须启用,但在大多数托管环境中,您无法自行设置.取决于托管公司是否允许您进行此设置AllowOverride Options.你可以很容易地找到:

  • 放到Options +FollowSymLinks/htdocs/public/.htaccess
  • 制作一个指向www/app.php的符号链接www/foo.php
  • 尝试访问foo.php
  • 或者,如果托管服务提供商提供对服务器日志的访问权限,您可以查看日志中是否存在错误.

如果此操作失败,您必须要求您的托管服务提供商Options +FollowSymLinks全局设置或AllowOverride Options全局允许.

方案

我实际上有4个场景(你可以在我的域上在线测试)使用不同的方法(假设主目录在你的情况下被命名为/ public):

1)avif.birds.cz重定向到birds.cz/avif/(规范) - 带符号链接的解决方案

/ public/avif - 符号链接到/ public/www/avif

/public/www/avif/.htaccess:

RewriteCond %{HTTP_HOST}    ^avif\.birds\.cz$ [NC]
RewriteRule ^(.*)$          %{ENV:proto}://birds.cz/avif/$1 [L]
Run Code Online (Sandbox Code Playgroud)

2)cap.birds.cz重定向到birds.cz/avif/some_url(根本不需要符号链接)

/public/.htaccess:

RewriteCond %{HTTP_HOST}    ^(www\.)?cap\.birds\.cz$ [NC]
RewriteRule ^(.*)$          %{ENV:proto}://birds.cz/avif/cap_intro.php [L]
Run Code Online (Sandbox Code Playgroud)

3)(www.)birds.cz/jpsp重定向到jpsp.birds.cz(规范)

/ public/jpsp - 符号链接到/ public/www/jpsp

/public/www/jpsp/.htaccess:

RewriteCond %{HTTP_HOST}    !^jpsp\.birds\.cz$ [NC]
RewriteCond %{HTTP_HOST}    !^$
RewriteRule ^(.*)$          %{ENV:proto}://jpsp.birds.cz/$1 [L]
Run Code Online (Sandbox Code Playgroud)

4)www.rorysi.cz - 由同一棵树服务的别名域(rorysi.cz必须保留为规范域)

此域的PHP源代码不同,位于/ public/www/rorysi下.

/public/www/.htaccess:

RewriteCond %{HTTP_HOST}    ^(www\.)?rorysi\.cz$ [NC]
RewriteCond %{REQUEST_URI}  !^/rorysi/ [NC]
RewriteCond %{REQUEST_URI}  !=/rorysi [NC]
RewriteCond %{REQUEST_URI}  !^/lib/ [NC]
RewriteRule ^(.*)$          %{ENV:proto}://www.rorysi.cz/rorysi/$1 [L]
Run Code Online (Sandbox Code Playgroud)

注意:lib目录包含PHP库和内联函数,因此我不希望将其重定向.

也许其中一些场景可能对您有所帮助或具有吸引力.


小智 2

1)确保您有

Options +FollowSymLinks 
Run Code Online (Sandbox Code Playgroud)

在您的 .htaccess 文件中。