【问题标题】:Symbolic link created using PHP script doesn't show up, but it's there?使用 PHP 脚本创建的符号链接不显示,但它在那里?
【发布时间】:2013-12-10 17:34:48
【问题描述】:

我的 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!

文件夹www主文件夹,它是前端控制器所在的文件夹。它绑定到mydmain.comwww.mydomain.com子域m.mydomain.comapi.mydomain.compublic 之一(即mapi)内的文件夹。

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

到目前为止我已经尝试过:

符号链接解决方案

创建指向www 文件夹的符号链接api。我使用了放在www 文件夹中的以下脚本:

<?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');

输出:

/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

符号链接已创建,但(这很奇怪)我无法通过 FTP 或文件管理器界面(网络)看到它的连接。前控制器不工作。符号链接在那里,如果我尝试创建一个与符号链接同名的文件夹,则会出现错误。

.htaccess 解决方案

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

【问题讨论】:

  • 你能在文件夹上运行ls -l吗(通过php的exec)?这将提供一些关于实际存在的信息!
  • @xav0989 我可以在 PHP(共享主机站点)中运行 ls 该命令吗?
  • 看看&lt;?php echo exec('ls -l');是否给你任何错误。这将列出您当前文件夹中的所有文件。您还应该运行getcwd();(请参阅@edwardrkerr 的回答)来确定您的实际位置。
  • 如果我理解了这个问题,你需要链接public/api -> public/www?那你为什么要从www 文件夹中做呢?从public 文件夹中的exec('ln -s www api') 怎么样(首先删除api 文件夹)?

标签: php symfony hosting subdomain shared-hosting


【解决方案1】:

我有完全相同的配置,并且成功了!唯一的区别是我将 api.domain.com 映射到 www.domain.com/api 而不是您的 www.domain.com,所以我的 api 符号链接指向 www/api,而不是 www。

.htaccess 解决方案

您可以使用对我下面描述的场景之一的修改,该修改不需要符号链接

/htdocs/public/.htaccess:

首先包含code to preserve HTTP/HTTPS protocol in redirections(我将在所有示例中假设此代码):

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

重定向代码:

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

这会将所有请求 api.domain.com/$1 重定向到 domain.com/api/$1。或者,如果您愿意,也可以使用 http://domain.com/$1

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

# 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]

符号链接解决方案

I) 关于符号链接,奇怪的是您在 FTP 上看不到符号链接。我在 FileZilla 中将其视为一个目录(好像它是一个硬链接)。尝试安装 FileZilla(并使用基于 TLS 的显式 FTP 进行安全身份验证)。

II) 必须启用Options +FollowSymLinks,但在大多数托管环境中you cannot set it yourself。取决于托管公司是否允许您通过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]

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]

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]

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]

注意:lib 目录包含 PHP 库和内联的东西,所以我不希望它被重定向。

也许其中一些场景对您有帮助或启发。

【讨论】:

  • 如果不对 .htaccess 中的域进行硬编码,这项工作是否可行?
  • @gremo 是的,您可以使用反向引用。请参阅我更新的帖子。我还添加了 HTTP/HTTPS 的智能处理
  • 感谢后面的参考提示。但我想用(反向引用)所有对 api.* 的请求重定向到 www 文件夹而不是 /api 路径......这可能吗?
【解决方案2】:

如果您的网络服务提供商的修改权限太有限,这实际上可能是不可能的。 您需要一一测试解决方案以查看它们是否有效。 首先检查 .htaccess 文件的访问权限,因为服务器通常需要非常严格的访问权限,如果不匹配,则忽略 .htaccess 文件。

如果在 .htaccess 访问后检查您的 Web SP 仍然不允许像 apoq 写的那样更改符号链接,那么我将按此顺序测试以下内容:

  • 首先是像 Tomas 写的那样测试重写。
  • 二是尝试 alias 和 scriptalias 因为 alias 只适用于 静态内容和脚本需要自己的别名规则。

但由于所有这些都取决于允许在您自己的 .htaccess 文件中更改的内容,因此您可能无法通过 .htaccess 文件更改任何内容。

【讨论】:

    【解决方案3】:

    1) 确保您拥有

    Options +FollowSymLinks 
    

    在您的 .htaccess 文件中。

    【讨论】:

      猜你喜欢
      • 2017-04-29
      • 2014-08-08
      • 2012-01-13
      • 2017-09-13
      • 1970-01-01
      • 2021-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多