Using strpos, check if given URL has 'any one' of the strings in the array?

1.4k Views Asked by At

I have a variable $url (who I have no control over) whose value is a URL (as a string). For example:

$url = 'http://www.youtube.com/watch?v=rSnzy2dZtsE';

I have a list of hosts (example.com) that I'd like to check against the $url, and see if any one of them matches the host in the URL.

I am doing it like this:

<?php

function itsme_custom_oembed( $html, $url, $attr, $post_id ) {

    // Supported video embeds
    $hosts = array( 'blip.tv', 'money.cnn.com', 'dailymotion.com', 'flickr.com', 'hulu.com', 'kickstarter.com', 'vimeo.com', 'vine.co', 'youtube.com' );

    foreach( $hosts as $host ) {

        // check if it's a supported video embed
        if( strpos( $url, $host ) === false )
            return $html;

        return '<div class="flex-video">'. $html .'</div>';

    }

}
add_filter( 'embed_oembed_html', 'itsme_custom_oembed', 10, 4 );

?>

But it's not working (i.e. strpos( $url, $host ) is always returning false), and as I see it, the problem is with the foreach construct. Especially because this works:

<?php

    function itsme_custom_oembed( $html, $url, $attr, $post_id ) {

        // Supported video embeds
        $host = 'youtube.com';

        // check if it's a supported video embed
        if( strpos( $url, $host ) === false )
            return $html;

        return '<div class="flex-video">'. $html .'</div>';

    }
    add_filter( 'embed_oembed_html', 'itsme_custom_oembed', 10, 4 );

?>

Clearly, foreach isn't meant for this purpose.

So, how am I supposed to check if given URL has any one of the strings in the array? (i.e. true if any one of the hosts in the list matches the host in the URL.)

3

There are 3 best solutions below

2
On

(Based on Jonathan Kuhn's answer and suggestions.) This does it:

<?php

function itsme_custom_oembed( $html, $url, $attr, $post_ID ) {

    // Supported video embeds
    $hosts = array( 'blip.tv', 'money.cnn.com', 'dailymotion.com', 'flickr.com', 'hulu.com', 'kickstarter.com', 'vimeo.com', 'vine.co', 'youtube.com' );

    foreach( $hosts as $host ) {

        // check if it's a supported video embed
        if( strpos( $url, $host ) !== false )
            return '<div class="flex-video">'. $html .'</div>';
        }

    }

    return $html;

}
add_filter( 'embed_oembed_html', 'itsme_custom_oembed', 10, 4 );

?>

Then an idea struck me; that I could do it in a much simpler way, like this:

<?php

function itsme_custom_oembed( $html, $url, $attr, $post_ID ) {

    // Supported video embeds
    $hosts = array( 'blip.tv', 'money.cnn.com', 'dailymotion.com', 'flickr.com', 'hulu.com', 'kickstarter.com', 'vimeo.com', 'vine.co', 'youtube.com' );

    foreach( $hosts as $host ) {

        // check if it's a supported video embed
        if( strpos( $url, $host ) !== false ) {
            $html = '<div class="flex-video">'. $html .'</div>';
            break;
        }

    }

    return $html;

}
add_filter( 'embed_oembed_html', 'itsme_custom_oembed', 10, 4 );

?>

Seems like a much better way to do what I am after.

9
On

Problem is that you are returning inside the loop. Once you return from a function, the function stops. So you end up checking the first value on the first run through the loop and return stopping the function from checking any subsequent iterations.

To fix it, you could just move the second return outside the loop. This would make the function loop over each value in the array until it found a match. If match found, function exits (return). If no match is found, it will hit the return after the loop.

function itsme_custom_oembed( $html, $url, $attr, $post_id ) {

    // Supported video embeds
    $hosts = array( 'blip.tv', 'money.cnn.com', 'dailymotion.com', 'flickr.com', 'hulu.com', 'kickstarter.com', 'vimeo.com', 'vine.co', 'youtube.com' );

    //loop over all the hosts
    foreach( $hosts as $host ) {

        // check if it's a supported video embed
        if( strpos( $url, $host ) === false )
            return $html;  //it was supported, so return from the original html from the function
    }

    //no hosts matched so return the original html wrapped in a div.
    return '<div class="flex-video">'. $html .'</div>';

}
5
On

I am not sure what you want to return but you can try to use this!

function itsme_custom_oembed( $html, $url, $attr, $post_id ) {

    $hosts = array('blip.tv', 'money.cnn.com', 'dailymotion.com', 'flickr.com', 'hulu.com', 'kickstarter.com', 'vimeo.com', 'vine.co', 'youtube.com');
    $success = false;

    foreach ($hosts as $host) {
        if (stripos($url, $host) !== false) {
            $success = true;
            break;
        }
    }

    if ($success) {
        // put your return when it DOES contain the host here
    }

    else {
        // put your return when it DOES NOT contain the host here
    }

}