如何检查php中是否存在url

如何检查php中是否存在url,php,validation,symfony,Php,Validation,Symfony,我正在做一个symfony2项目,我正在做一个自定义约束来检查url是否存在。我四处查看发现: 问题是如果我尝试一个完全随机的地址,比如www.flskkhfkhsdf.com,它会给我一个警告并停止我的代码。还有别的办法吗 警告: 警告:get_headers():php_network_getaddresses:getaddrinfo失败: 目前还不知道这样的主机 这是我的密码: <?php namespace AdminBundle\Validator\Constraints;

我正在做一个symfony2项目,我正在做一个自定义约束来检查url是否存在。我四处查看发现:

问题是如果我尝试一个完全随机的地址,比如www.flskkhfkhsdf.com,它会给我一个警告并停止我的代码。还有别的办法吗

警告:

警告:get_headers():php_network_getaddresses:getaddrinfo失败: 目前还不知道这样的主机

这是我的密码:

<?php

namespace AdminBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

Class ContrainteUrlExistValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint)
    {
        $file_headers = get_headers($value);
        if($file_headers[0] == 'HTTP/1.1 404 Not Found') {
            $this->context->buildViolation($constraint->message)
                ->setParameter('%string%', $value)
                ->addViolation();
        }
    }
}

我不知道Symfony特定的解决方案,我将为您提供一些核心PHP函数

这就是你需要的。在有效主机名上,它将返回ip地址。对于不存在的主机名,它将返回未修改的主机名

所以你可以做一些像

if (gethostbyname($hostname) == $hostname) {
    $this->context->buildViolation...
}
当然,您必须从给定的URL中提取基本主机名,但您可以使用以下方法:

当然,您必须首先验证URL,但您可以通过以下方式进行验证:

编辑:完整代码 完整代码可以大致如下所示:

public function validate($value, Constraint $constraint)
{
    if ( ! filter_var($value, FILTER_VALIDATE_URL)) {
        $this->failValidation();
        return;
    }

    $hostname = parse_url($value, PHP_URL_HOST);
    if (empty($hostname)) {
        $this->failValidation();
        return;
    }

    if (gethostbyname($hostname) == $hostname) {
        $this->failValidation();
        return;
    }
}

protected function failValidation($value, Constraint $constraint) 
{
    $this->context->buildViolation($constraint->message)
            ->setParameter('%string%', $value)
            ->addViolation();
}

您可以使用任何HTTP客户端库(如Guzzle或Buzz)来访问URL。如果发生任何错误,这些库将抛出异常


使用HTTP方法“HEAD”避免下载整个页面。

我找到了一个有效的解决方案:

<?php

namespace AdminBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

Class ContrainteUrlExistValidator extends ConstraintValidator
{
    public function validate($url, Constraint $constraint)
    {
        //Vérifie si l'url peut être vide
        if(empty($url)&&$constraint->peutEtreVide)
        {
            return;
        }

        //Pattern pour trouver les url qui commence par http:// ou https://
        $pattern='/^(https?:\/\/)/';

        //Valide l'url et s'assure le preg_match a trouvé un match
        if(filter_var($url, FILTER_VALIDATE_URL)&&!empty(preg_match($pattern, $url, $matches)))
        {
            //Trouve l'host
            $hostname=parse_url($url, PHP_URL_HOST);

            //Tente de trouver l'adresse IP de l'host
            if (gethostbyname($hostname) !== $hostname)
            {
                //Cherche les données de l'entête
                $headers=get_headers($url);

                //Tente de trouver une erreur 404
                if(!strpos($headers[0], '404'))
                {
                    return;
                }
            }
        }

        //Crée une erreur
        $this->context->buildViolation($constraint->message)
                    ->setParameter('%string%', $url)
                    ->addViolation();
    }
}

你是指任何URL吗?例如外部(来自应用程序)URL?它查找返回
404
响应的服务器。如果你写的域名不存在,没有服务器会回复,你不可能得到
404
。您需要首先检查域(主机)是否存在。正如错误消息所说,“gethostbyname”是php的本机函数吗,?我需要按照什么顺序使用这些代码才能使其工作?是的,“gethostbyname”是一个本机PHP函数,您可以通过下面的链接看到。我已编辑我的答案以显示完整代码。
public function validate($value, Constraint $constraint)
{
    if ( ! filter_var($value, FILTER_VALIDATE_URL)) {
        $this->failValidation();
        return;
    }

    $hostname = parse_url($value, PHP_URL_HOST);
    if (empty($hostname)) {
        $this->failValidation();
        return;
    }

    if (gethostbyname($hostname) == $hostname) {
        $this->failValidation();
        return;
    }
}

protected function failValidation($value, Constraint $constraint) 
{
    $this->context->buildViolation($constraint->message)
            ->setParameter('%string%', $value)
            ->addViolation();
}
<?php

namespace AdminBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

Class ContrainteUrlExistValidator extends ConstraintValidator
{
    public function validate($url, Constraint $constraint)
    {
        //Vérifie si l'url peut être vide
        if(empty($url)&&$constraint->peutEtreVide)
        {
            return;
        }

        //Pattern pour trouver les url qui commence par http:// ou https://
        $pattern='/^(https?:\/\/)/';

        //Valide l'url et s'assure le preg_match a trouvé un match
        if(filter_var($url, FILTER_VALIDATE_URL)&&!empty(preg_match($pattern, $url, $matches)))
        {
            //Trouve l'host
            $hostname=parse_url($url, PHP_URL_HOST);

            //Tente de trouver l'adresse IP de l'host
            if (gethostbyname($hostname) !== $hostname)
            {
                //Cherche les données de l'entête
                $headers=get_headers($url);

                //Tente de trouver une erreur 404
                if(!strpos($headers[0], '404'))
                {
                    return;
                }
            }
        }

        //Crée une erreur
        $this->context->buildViolation($constraint->message)
                    ->setParameter('%string%', $url)
                    ->addViolation();
    }
}