1

我正在编写一个简单的函数,它将包含 url 的字符串转换为可点击的链接。转换本身很简单,但如果字符串包含协议前缀之一,则作为基本验证的一部分似乎非常困难。

目前我的代码如下所示:

<?php

function link2code($link) {
    if (stripos($link, 'http://' or 'https://' or 'ftp://' or 'ftps://') === true) {
        return "<a href=\"$link\">$link</a>";
    } else {
        echo('Please provide whole link with protocol part, for example: http://myawesomewebsite.com');
    }
}

echo link2code("http://127.0.0.1");

如您所见,我想返回布尔值,告诉针是否在大海捞针中。我怎样才能实现它?

4

7 回答 7

4

您可以preg_match为此使用:

if(preg_match("~^(ht|f)tps?://~i", $link)) { //...etc
于 2017-07-15T19:44:20.903 回答
3

签出此代码:

class Test
{

     public function index()
     {
         $link = "http://127.0.0.1";
         $this->checkLink("http://127.0.0.1");        //Yes
         $this->checkLink("hsttp://127.0.0.1");        //No
     }

     private function checkLink($link)
     {
         if (stripos($link, 'http://') !== false
             || stripos($link, 'http://') !== false
             || stripos($link, 'ftp://') !== false
             || stripos($link, 'ftps://') !== false)
         {
             echo 'Yes';
         }
         else
         {
             echo 'No';
         }
      }

}
于 2017-07-15T19:43:44.910 回答
1

您可以通过定义自定义函数进行迭代并找到 if match found 创建一个链接。

function strPosition($haystack, $needle, $offset=0) {
  if (!is_array($needle)) $needle = array($needle);
    foreach ($needle as $query) {
      if (strpos($haystack, $query, $offset) !== false) return true; // stop on first true result
    }
    return false;
}

function link2code($link) {
  $array = array('http://', 'https://', 'ftp://', 'ftps://');

  $match = strPosition($link, $array);
  if ($match == true) {
    return "<a href=\"$link\">$link</a>";
  } else {
    echo('Please provide whole link with protocol part, for example: http://myawesomewebsite.com');
  } 
}
于 2017-07-15T19:43:41.737 回答
1

可以使用正则表达式来完成。尽管多次使用 stripos() 也可以。这条线会更长,但可能更便宜。

为了可读性,我更喜欢正则表达式

<?php

function link2code($link) {
    if (preg_match('#^(https?|ftps?)://#i', $link)) {
        return "<a href=\"$link\">$link</a>";
    } else {
        echo('Please provide whole link with protocol part, for example: http://myawesomewebsite.com');
    }
}

echo link2code("http://127.0.0.1");
于 2017-07-15T19:47:00.893 回答
1

您可以尝试改写问题:

不要检查链接中的协议是否之一,而是尝试检查链接中的协议是否是协议之一:

function link2code($link) {

    $scheme = parse_url($link, PHP_URL_SCHEME);
    if(!in_array($scheme,['http','https','ftp','ftps']) {
        return "<a href=\"$link\">$link</a>";
    } else { 
        echo ()
    }
}

在您的问题范围之外:

你的函数做不同的事情:

  • 它验证网址
  • 它返回字符串或返回 void
  • 在某些情况下,它会产生共鸣。

您可以尝试将验证与格式化分开,并确保您的函数始终返回一个字符串,或引发异常。

function link2code($link) {
    if(validateLink($link)) {
        return "<a href=\"$link\">$link</a>";
    } else {
        throw new \Exception("Please provide whole link with protocol part, for example: http://myawesomewebsite.com'");
    }
}

function validateLink($link) {
    $scheme = parse_url($link, PHP_URL_SCHEME);
    return in_array($scheme,['http','https','ftp','ftps']);
}
于 2017-07-15T19:49:49.050 回答
0

您可以使用 in_array()。
http://php.net/manual/en/function.in-array.php

function link2code($link) {
    $arr = array('http:/', 'https:', 'ftp://', 'ftps:/');
    If(in_array(substr($link,0,6), $arr)){
        return "<a href=\"$link\">$link</a>";
    } else {
         echo('Please provide whole link with protocol part, for example: http://myawesomewebsite.com');
    }
}

echo link2code("https://127.0.0.1");

https://3v4l.org/meI1r
该数组包含最小公共字符数(6),以便我可以在函数中与相同的字符进行比较。
因此,如果它们与数组不匹配,substr 将查看前六个字符,它不是唯一的链接字符串。

意味着字符串click here https://127.0.0.1将失败

当然,如果您不需要验证它是仅链接字符串,则可以从代码中删除 substr 并在数组中添加“完整”项。

于 2017-07-15T19:59:31.910 回答
0

尝试使用正则表达式和preg_match

function link2code($link) {
    if ( ! preg_match('/^(http(s)?|ftp(s)?):\/\//i', $link)) {
        echo 'Please provide whole link with protocol part, for example: http://myawesomewebsite.com';
        return FALSE;
    }
    return sprintf('<a href="%1$s">%1$s</a>', $link);
}

echo link2code("http://127.0.0.1");
echo link2code("https://127.0.0.1");
于 2017-07-15T20:11:05.797 回答