在不使用数据库查询或主机文件的情况下检查子域是否存在的更好方法

Better way to check if subdomain exists without using database query or hosts file

我正在使用 symfony2,在我的学生宿舍申请中,我正在为每所大学创建动态子域,我正在使用通配符子域条目配置虚拟主机,因此任何子域都是有效的。

如何检查子域是否已注册并属于大学,以及如何将其与随机输入的 非用户注册 子域有效?

如果我使用数据库查询,那么来自好奇用户的每次随机访问都会导致大量数据库查询,并且主机文件的使用会太慢(不是最佳实践)

请建议使用 php 或 symfony 或你们知道的任何其他技术的有效方法

(附加信息)会有一个 'free trial' 选项,这样会产生很多子域,因为任何人和每个人都会开始免费试用,这是我正在尝试的一个很好的例子实现会是这样 StudyStays

-谢谢

您可以缓存所有每个子域请求(使用 Doctrine 缓存之类的东西作为您使用的任何缓存系统的包装器),以便每个后续检查只需要检查缓存而不是数据库。

此外,当 adding/removing/updating 您的子域对象时,您可以更新缓存值以使其全部保持最新。

app/config/config.yml

为 Doctrine Cache Bundle 设置你的提供者,更多信息见the docs(显然你需要将 Doctrine Cache Bundle 添加到你的供应商和 AppKernel)。

doctrine_cache:
    providers:
        acme_subdomain:
            type: filesystem # apc, array, redis, etc
            namespace: acme_subdomain

Acme\YourBundle\Registry\SubdomainRegistry

创建一个可以检查子域状态并在需要时更新缓存的注册表。此示例将状态存储为字符串而不是布尔值,因为(据我所知)"not found" 键将 return 为 false 而不是 null。

use Doctrine\Common\Cache\Cache;
use Doctrine\Common\Persistence\ObjectManager;

class SubdomainRegistry implements SubdomainRegistry
{
    const REGISTERED   = 'registered';
    const UNREGISTERED = 'unregistered';

    /**
     * @param ObjectManager
     */
    protected $manager;

    /**
     * @param Cache
     */
    protected $cache;

    public function __construct(ObjectManager $manager, Cache $cache)
    {
        $this->manager = $manager;
        $this->cache = $cache;
    }

    /**
     * @param string $subdomain
     * @return boolean
     */
    public function isSubdomainRegistered($subdomain)
    {
        // If subdomain is not in cache update cache
        if (!$this->cache->has($subdomain)) {
            $this->updateRegistry($subdomain);
        }

        return self::REGISTERED === $this->cache->get($subdomain);
    }

    /**
     * @param string $subdomain
     * @return boolean
     */
    public function registerSubdomain($subdomain)
    {
        $this->cache->set($subdomain, self::REGISTERED);

        return $this;
    }

    /**
     * @param string $subdomain
     * @return boolean
     */
    public function unregisterSubdomain($subdomain)
    {
        $this->cache->set($subdomain, self::UNREGISTERED);

        return $this;
    }

    /**
     * @param string $subdomain
     * @return null
     */
    private function updateRegistry($subdomain)
    {
        $object = $this->manager->findOneBy(array('subdomain' => $subdomain);

        // $object->isActive() assume you are storing all subdomains after cancelling
        // and setting it to inactive. You could put your own real logic here
        if (null === $object || !$object->isActive()) {
            $this->unregisterSubdomain($subdomain);

            return null;
        }

        $this->registerSubdomain($subdomain);
    }

然后当您注册或取消注册您的子域时,您可以在该方法中添加对注册表的调用。

例如...

$subdomain = new Subdomain();
// Subdomain as a property of subdomain seems weird to me
// but as I can't immediately think of anything better I'll go with it
$subdomain->setSubdomain('acme');
// .. subdomain details
$this->manager->persist($subdomain);
$this->manager->flush();
$this->registry->registerSubdomain($subdomain->getSubdomain());