【问题标题】:How to check if the an url exist in php如何检查一个url是否存在于php中
【发布时间】:2015-07-03 20:29:31
【问题描述】:

我正在开发一个 Symfony 2 项目,我正在制作一个自定义约束来检查一个 url 是否存在。我检查了一下,发现了这个:

How can I check if a URL exists via PHP?

问题是,如果我尝试像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();
        }
    }
}

【问题讨论】:

  • 您是指任何网址吗?比如外部(来自应用程序)URL?
  • 它寻找返回404响应的服务器。如果你写一个不存在的域名,没有服务器会回复,你不可能得到一个404。您需要先检查域(主机)是否存在。就像错误消息所说的那样。

标签: php validation symfony


【解决方案1】:

我不了解 Symfony 特定的解决方案,我会给你一些核心的 PHP 功能。

gethostbyname 是您所需要的。在有效的主机名上,它将返回 IP 地址。在不存在的主机名上,它将返回未修改的主机名。

所以你可以做类似的事情

if (gethostbyname($hostname) == $hostname) {
    $this->context->buildViolation...
}

当然,您必须从给定的 URL 中提取基本主机名,但您可以使用 parse_url

$hostname = parse_url($url, PHP_URL_HOST)

当然,您必须先验证 URL,但您可以使用 filter_var

if ( ! filter_var($url, FILTER_VALIDATE_URL)) {
    // URL not valid
}

编辑:完整代码

完整的代码或多或少是这样的:

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();
}

【讨论】:

  • 'gethostbyname' 是 php 的原生函数吗?我需要按什么确切顺序使用这些代码才能使其工作?
  • 是的,“gethostbyname”是一个原生 PHP 函数,您可以通过链接看到。我已经编辑了我的答案以显示完整的代码。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    我找到了一个可行的解决方案:

    <?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();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-17
      • 1970-01-01
      • 1970-01-01
      • 2011-03-26
      相关资源
      最近更新 更多