-1

I'm trying to create a function that calls a value from a Wordpress custom field ("_videourl" for a YouTube video URL) and then uses PHP trim to cut it down to just the YouTube video ID. I found a javascript function that cuts down URLs to just the ID but I have no idea how I'd be able to translate that into php (function below):

     function youtubeIDextract(url) 
     { 
     var youtube_id; 
     youtube_id = url.replace(/^[^v]+v.(.{11}).*/,"$1"); 
     return youtube_id; 
     }

This PHP function would be used inside the loop so I think I would have to use variables, but I'm really just a noob so I have no idea what to do. Can anyone help by sharing their coding expertise in helping me create a PHP function?

EDIT:SOLVED

After some experimentation, I found a solution. I wanted to return and post it so that others also in need would have somewhere to start from.

function getYoutubeId($ytURL) 
    {
        $urlData = parse_url($ytURL);
        //echo '<br>'.$urlData["host"].'<br>';
        if($urlData["host"] == 'www.youtube.com') // Check for valid youtube url
        {
            $ytvIDlen = 11; // This is the length of YouTube's video IDs

            // The ID string starts after "v=", which is usually right after 
            // "youtube.com/watch?" in the URL
            $idStarts = strpos($ytURL, "?v=");

            // In case the "v=" is NOT right after the "?" (not likely, but I like to keep my 
            // bases covered), it will be after an "&":
            if($idStarts === FALSE)
                $idStarts = strpos($ytURL, "&v=");
            // If still FALSE, URL doesn't have a vid ID
            if($idStarts === FALSE)
                die("YouTube video ID not found. Please double-check your URL.");

            // Offset the start location to match the beginning of the ID string
            $idStarts +=3;

            // Get the ID string and return it
            $ytvID = substr($ytURL, $idStarts, $ytvIDlen);

            return $ytvID;
        }
        else
        {
            //echo 'This is not a valid youtube video url. Please, give a valid url...';
            return 0;
        }

    } 
Matt
  • 570
  • 4
  • 11
  • 3
    Does this solve your problem: http://stackoverflow.com/questions/2936467/parse-youtube-video-id-using-preg-match/6382259#6382259 ? – Peter Boughton Aug 28 '11 at 14:23
  • I higly doubt that YouTube video ids are always 11 chars long. Your regex may be wrong. – MartinodF Aug 28 '11 at 14:23
  • I found some helpful tips in the link Peter, but it doesn't seem any solutions were able to filter out the extra arguments at the end (which is what I need too). I was doing some research and found this: http://www.halgatewood.com/php-get-the-youtube-video-id-from-a-youtube-url/ but I'm not sure how to change it to grab the custom field value for the field '_videoembed' – Matt Aug 28 '11 at 17:29
  • @MartinodF- Indeed they are exactly 11 characters long. – Benjam Sep 09 '11 at 02:05
  • possible duplicate of [Get YouTube ID from URL regex pattern](http://stackoverflow.com/questions/10404752/get-youtube-id-from-url-regex-pattern) – T.Todua Jul 10 '14 at 16:41
  • youtube-nocookie.com is a valid youtube-host. – imme Mar 05 '15 at 13:45

3 Answers3

12

I had to deal with this for a PHP class i wrote a few weeks ago and ended up with a regex that matches any kind of strings: With or without URL scheme, with or without subdomain, youtube.com URL strings, youtu.be URL strings and dealing with all kind of parameter sorting. You can check it out at GitHub or simply copy and paste the code block below:

/**
 *  Check if input string is a valid YouTube URL
 *  and try to extract the YouTube Video ID from it.
 *  @author  Stephan Schmitz <eyecatchup@gmail.com>
 *  @param   $url   string   The string that shall be checked.
 *  @return  mixed           Returns YouTube Video ID, or (boolean) false.
 */        
function parse_yturl($url) 
{
    $pattern = '#^(?:https?://)?(?:www\.)?(?:youtu\.be/|youtube\.com(?:/embed/|/v/|/watch\?v=|/watch\?.+&v=))([\w-]{11})(?:.+)?$#x';
    preg_match($pattern, $url, $matches);
    return (isset($matches[1])) ? $matches[1] : false;
}

To explain the regex, here's a spilt up version:

/**
 *  Check if input string is a valid YouTube URL
 *  and try to extract the YouTube Video ID from it.
 *  @author  Stephan Schmitz <eyecatchup@gmail.com>
 *  @param   $url   string   The string that shall be checked.
 *  @return  mixed           Returns YouTube Video ID, or (boolean) false.
 */        
function parse_yturl($url) 
{
    $pattern = '#^(?:https?://)?';    # Optional URL scheme. Either http or https.
    $pattern .= '(?:www\.)?';         #  Optional www subdomain.
    $pattern .= '(?:';                #  Group host alternatives:
    $pattern .=   'youtu\.be/';       #    Either youtu.be,
    $pattern .=   '|youtube\.com';    #    or youtube.com
    $pattern .=   '(?:';              #    Group path alternatives:
    $pattern .=     '/embed/';        #      Either /embed/,
    $pattern .=     '|/v/';           #      or /v/,
    $pattern .=     '|/watch\?v=';    #      or /watch?v=,    
    $pattern .=     '|/watch\?.+&v='; #      or /watch?other_param&v=
    $pattern .=   ')';                #    End path alternatives.
    $pattern .= ')';                  #  End host alternatives.
    $pattern .= '([\w-]{11})';        # 11 characters (Length of Youtube video ids).
    $pattern .= '(?:.+)?$#x';         # Optional other ending URL parameters.
    preg_match($pattern, $url, $matches);
    return (isset($matches[1])) ? $matches[1] : false;
}
eyecatchUp
  • 10,032
  • 4
  • 55
  • 65
0

Best solution I have found;

 function GetYouTubeId($url)
 {
 preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $url, $match);
 $youtube_id = $match[1];
 return $youtube_id;
 }
Debbie Kurth
  • 403
  • 3
  • 16
0

Assuming the regex is correct, you could use preg_replace

$youtubeId = preg_replace('/^[^v]+v.(.{11}).*/', '$1', $url);

You may also be interested in str_replace or substr as alternatives.

adlawson
  • 6,303
  • 1
  • 35
  • 46