function to check if anchor tags contain href attributes with 301 I made this function to test if the content has 301 redirections.. Please can you help me optimize it better because it's too slow
function contains_http_301_link($content, $current_site){
$pattern = '~&lt;a(.*?)href=&quot;([^&quot;]+)&quot;(.*?)&gt;~';
$links = array();
// Check if there is a url in the content
if(preg_match_all($pattern, $content, $urls)) {
    foreach($urls[0] as $url){
        // get external links

        if ( !strpos( $url, $current_site )) {                                   // Is an external link
            $vowels = array('&quot;' ,&quot;&lt;a&quot;, &quot; &quot;, &quot;href&quot;, &quot;=&quot;, &quot;&gt;&quot;);
            $links[] = str_replace($vowels, &quot;&quot;, $url);
        }
    }
}
foreach ($links as $link) {
    $_headers = @get_headers($link,1); 
    if($_headers &amp;&amp; strpos( $_headers[0], '301')) { 
        return true;
    } 
}
return false;
}
I have never attempted such a task, but I will assume that you entertained the cURL techniques (including CURLOPT_NO_BODY and CURLINFO_HTTP_CODE) as suggest at 1 and 2.
As for parsing an html document, using regex may outperform a legitimate parser, but you might enjoy more accurate scaping if you use a DOM parser.
Since your focus is on performance, I'll [cringe] suggest regex to parse your html.
Your pattern ~&lt;a(.*?)href=&quot;([^&quot;]+)&quot;(.*?)&gt;~ uses lazy quantifiers and this can slow things down a little.  Also, your &lt;a(.*?)href will allow the matching of &lt;a data-href and &lt;abbr href -- which is not what you intend.
Your intention is to capture ONLY the url inside of the href attribute, so don't bother matching more than you need.  You can probably get away with a wordboundary after a and a space before href, then reset the fullstring match with \K to only retain the href's value.  If this isn't strong enough validation, then you could add a lookahead to confirm that the opening tag is completed properly.

~&lt;a\b.*? href=&quot;\K[^&quot;]+~ or
~&lt;a\b.*? href=&quot;\K[^&quot;]+(?=&quot;.*?&gt;)~

Either way, your code can skip the sanitizing step.  Thank goodness because $vowels contains data that are not all vowels.
strpos() can return false or 0 as the offset.  This means that you must not rely on the type juggled condition using merely !.  You must explicitly check for false or if you are on a php version that enjoys str_contains() -- that'll work.
I personally condemn the use of the &quot;stfu operator&quot; (@), but because I am not familiar with this task, I'll avoid calling it an abomination.
function contains_http_301_link(string $content, string $current_site): bool
{
    preg_match_all('~&lt;a\b.*? href=&quot;\K[^&quot;]+~', $content, $matches);
    foreach ($matches[0] as $url) {
        if (strpos($url, $current_site) !== false) {
            continue;
        }
        $headers = @get_headers($url, 1);
        if($headers &amp;&amp; strpos($headers[0], '301') !== false) {
            return true;
        } 
    }
    return false;
}

I could possibly include the $current_site filtration into the regex but it may do more harm than good.

If you were going to entertain (and benchmark) a DOM parser script, then perhaps use this:
function contains_http_301_link(string $content, string $current_site): bool
{
    $dom = new DOMDocument; 
    $dom-&gt;loadHTML($content);
    $xpath = new DOMXPath($dom);
    foreach ($xpath-&gt;query(&quot;//a[not(contains(@href, '$current_site'))]/@href&quot;) as $href) {
        $headers = @get_headers($href-&gt;nodeValue, 1);
        if($headers &amp;&amp; strpos($headers[0], '301') !== false) {
            return true;
        } 
    }
    return false;
}