Service status checker... Is there a more efficient way?
PHP is not suitable for multi-threading. Though there are some extensions that offer ways of multithreading, they all are, basically, hacks IMO. The best way forward in your case would be: to use a tool that is async by nature, and update the url's as you go along.
Thankfully, such a thing exists, and it goes by the name JavaScript (AJAX calls), here's what I'd do:

foreach ($sites as $key =&gt; $value)
{
    echo '&lt;tr&gt;&lt;td&gt;&lt;strong&gt;',$key, '&lt;/strong&gt; (', $value, ')&lt;/td&gt;',
    '&lt;td class="pending"&gt;&lt;img src="loading.gif"/&gt;&lt;/td&gt;&lt;/tr&gt;';
}


This will present the client with a complete overview of urls (since that's what you say they are), each row showing a gif (optional, of course) of one of those circular loading things This one, for example.
On the page, have script that goes something like this:

window.addEventListener('load',function l()
{
    var pending = document.querySelectorAll('td.pending'),i=0,
    callNext = function(elem)
    {
        var urlMatch = elem.parentNode.cells[0].textContent.match(/\(([^)]+)/)[1],
        xhr = new XMLHttpRequest;
        xhr.open('POST','ajax.php', true);
        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
        xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        xhr.onreadystatechange = callback;
        xhr.send('url=' + encodeURI(urlMatch));
    },
    callback = function()
    {
        if (this.readyState === 4 &amp;&amp; this.status === 200)
        {
            var resp = JSON.parse(this.responseText);
            pending[i].setAttribute('class','error');//default error
            if (resp.success)
            {
                pending[i].setAttribute('class','success');
            }
            pending[i].replaceChild(
                document.createTextElement(resp.cellText),
                pending[i].firstChild
            );
            if (++i &lt; pending.length)
            {
                callNext(pending[i]);
            }
        }
    };
    callNext(pending[i]);
    window.removeEventListener('load',l,false);
},false);


Then, the ajax.php script, could just be the Visit function (BTW: please follow the PHP-FIG-coding standards as much as possible, and lower-case that function name). Instead of $url just use:

$url = isset($_POST['url']) &amp;&amp; filter_var($_POST['url'], FILTER_VALIDATE_URL) ? $_POST['url'] : false;
if (!$url)
{
    echo json_encode(array('cellText' =&gt; 'invalid URL'));
    exit;
}
//do curl request
echo json_encode(array('success' =&gt; true, 'cellText' =&gt; 'valid'));//or invalid, depending on curl results


This way, the client gets to see the page quite quickly, and sees it's being updated once every 6~7 seconds, depending on how long the curl request takes to complete.
In addition to that, look into caching extensions, such as APC, and set the cache options for the cUrl requests, too. This usually requires some trial and error to find the right balance...