【问题标题】:Symfony dynamic subdomainsSymfony 动态子域
【发布时间】:2011-02-28 16:36:41
【问题描述】:

我正在尝试将子域与 symfony 中的客户 ID 匹配。

即我有 customer1.example.com 和 customer2.example.com

域存储在一个表中。

当用户访问customer1.example.com时,我想获取子域,在数据库中查找域名,一旦匹配,它将为该客户部署应用配置,然后将customer_Id存储在一个全局属性,所以我确切地知道我在整个应用程序中与哪个客户打交道。虚拟主机将具有相关的通配符服务器名。

您是否成功地做到了这一点,如果是,如何做到的?如果没有,任何想法都会有很大帮助!

我正在考虑使用过滤器来做到这一点。

:-)

【问题讨论】:

  • 谢谢!希望有人知道答案! :-)

标签: php symfony1 filter subdomain


【解决方案1】:

因为您要加载不同的应用程序,过滤器无济于事。只需使用前端控制器(index.php)提取子域,如果应用程序目录存在,则加载应用程序(否则为404)。您甚至可以将 id 存储在应用配置中。

【讨论】:

  • 嘿马雷克。我没有部署不同的应用程序,我只想使用 sudomain 作为参数变量。例如:我不想拥有example.com/company1/admin,而是希望为每个客户拥有company1.example.com/admin 相同的应用程序,但我使用子域来获取公司相关数据。我昨晚成功了。我创建了一个过滤器(domainMatchFilter.class.php)。
  • 我抓取了子域,在客户表上进行了搜索以匹配域(表中的域字段上有一个索引)。一旦找到它,它就会使用结果集中的客户对象设置一个配置变量。即 sfConfig::set("customer", $customer)。如果没有找到客户,它会重定向到主页 (example.com)。您认为重定向到显示该客户不存在等的页面会更好吗?这个过滤器在每个页面请求上运行,这有点慢,因为它每次都查询数据库,但是,这是我知道如何做到这一点的唯一方法。
  • 我希望它像 uservoice.com 一样工作。你注册了,你就得到了自己的域名,即 company1.uservoice.com 等,这比 uservoice.com/company1 好得多
  • 好吧,我误会了。 filter 方法是正确的方法,不用担心额外的查询。为了可用性,你应该说这个客户不存在。
【解决方案2】:

我正在做类似的事情。请注意,我没有尝试过这种确切的设置。

$tokens = explode('.', $_SERVER['SERVER_NAME'], 2);
$app = $tokens[0] == 'www' ? 'default' : $tokens[0]; //assumes you aren't allowing www.app.example.com, change if you are

try
{
  $appConfiguration = ProjectConfiguration::getApplicationConfiguration($app, 'prod', false);
}
catch(InvalidArgumentException $e) //thrown if app doesn't exist
{
  $fallbackConfiguration = ProjectConfiguration::getApplicationConfiguration('default', 'prod', false); 
  $context = sfContext::createInstance($fallbackConfiguration);
  $request = $context->getRequest();
  $request->setParameter('module', 'default'); //set what route you want an invalid app to go to here
  $request->setParameter('action', 'invalidApplication');
  $context->dispatch();
}
if (isset($appConfiguration))
{
  sfContext::createInstance($appConfiguration)->dispatch();
}

【讨论】:

    【解决方案3】:

    看看sfDomainRoutePlugin - 它可以满足您的需求。但是,在其当前版本中,您没有获得 Propel 或 DoctrineRoute 功能,这意味着您必须根据插件返回的子域参数手动查找客户。示例:

    app/frontend/config/routing.yml

    # pick up the homepage
    homepage:
      url:          /
      class:        sfDomainRoute
      param:        { module: homepage, action: index }
      requirements:
        sf_host:    [www.example.com, example.com]
    
    # catch subdomains for customers
    customer_subdomain:
      url:          /
      class:        sfDomainRoute
      param:        { module: customer, action: index }
    

    app/frontend/modules/customer/actions.class.php

    public function executeIndex(sfWebRequest $request)
    { 
      // get the subdomain parameter
      $this->subdomain = $request->getParameter('subdomain');
      // retrieve customer (you have to create the retrieveBySubdomain method)
      $this->customer = CustomerPeer::retrieveBySubdomain($this->subdomain);
    }
    

    这只是一个示例,但我自己也使用了类似的方法,并且该插件执行广告宣传的工作。祝你好运。

    如果你喜欢冒险,你可以看看“More with symfony book”中的第 2 章。这将帮助您理解 sfDomainRoutePlugin 中的代码。

    【讨论】:

      【解决方案4】:

      还需要将您的域设置为通配符域,否则您需要为每个客户端手动创建每个子域。

      另一个不那么依赖 symphony 的解决方案是使用 .htaccess

          <IfModule mod_rewrite.c>
         Options +FollowSymLinks
         Options +Indexes
         RewriteEngine On
         RewriteBase /
         RewriteCond %{HTTP_HOST} !www.domain.com$ [NC]
         RewriteCond %{HTTP_HOST} ^(www.)?([a-z0-9-]+).domain.com [NC]
         RewriteRule (.*) $1?sub=%2&page=$1&domain=%{HTTP_HOST} [QSA,L]
      <IfModule>
      

      该代码基本上会将子域、域和请求的页面发送到请求的页面。然后在 php 中,您可以检查它是否等于您的客户端用户名。并允许您同时为您的客户使用托管域名。

      希望对你有帮助。

      【讨论】:

        猜你喜欢
        • 2011-10-04
        • 2014-10-03
        • 1970-01-01
        • 1970-01-01
        • 2018-08-23
        • 2011-04-27
        • 2014-05-22
        • 1970-01-01
        • 2013-02-10
        相关资源
        最近更新 更多