Search code examples
phpregexpreg-matchpreg-replace-callbackcreate-function

Need help understanding create_function() and regex


After allot of searching around SO and other forums also stumbling over various php function documentation, I tried to edit a function that I found on here(converts URLs to clickable links) so it will also handle embedded video, unfortunately my skill set is poor and I believe I don't fully understand create_function() to be successful at this.

So here's my scrambled egg code:

private function _check4Links($text){
    $pattern  = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#';
    $callback = create_function('$matches', '
       $url       = array_shift($matches);
       $url_parts = parse_url($url);

       if(preg_match("%(?:youtube\.com/(?:user/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i", $url, $match)){
            return sprintf(\'<iframe title="YouTube video player" class="youtube-player" type="text/html" width="400" height="244" src="http://www.youtube.com/embed/\'.$match[1].\'" frameborder="0" allowFullScreen></iframe>\', $url, $text);
       }else{

            $text = parse_url($url, PHP_URL_HOST) . parse_url($url, PHP_URL_PATH);
            $text = preg_replace("/^www./", "", $text);

            $last = -(strlen(strrchr($text, "/"))) + 1;
            if ($last < 0) {
               $text = substr($text, 0, $last) . "&hellip;";
            }

            return sprintf(\'<a target="_blank"rel="nofollow" href="%s">%s</a>\', $url, $text);
       }');

    return preg_replace_callback($pattern, $callback, $text);
}

I should also mention that i'm not looking for someone to just show me the correct code, I'm looking for someone to explain to me why my code is not working and what i am doing wrong. Thank you for your time :)


Solution

  • Here is a fix:

    <?php
    function _check4Links($text){
        $pattern  = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#';
    
        return preg_replace_callback($pattern, 'fnc', $text);
    }
    
    function fnc($matches) {
        $url       = array_shift($matches);
        $url_parts = parse_url($url);
    
        if(preg_match("%(?:youtube\.com/(?:user/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^\"&?/ ]{11})%i", $url, $match)){
              return '<iframe title="YouTube video player" class="youtube-player" type="text/html" width="400" height="244" src="http://www.youtube.com/embed/'.$match[1].'" frameborder="0" allowFullScreen></iframe>';
        } else {
    
            $text = parse_url($url, PHP_URL_HOST) . parse_url($url, PHP_URL_PATH);
            $text = preg_replace("/^www./", "", $text);
    
            $last = -(strlen(strrchr($text, "/"))) + 1;
            if ($last < 0) {
                $text = substr($text, 0, $last) . "&hellip;";
            }
    
            return sprintf('<a target="_blank"rel="nofollow" href="%s">%s</a>', $url, $text);
            }
        }
    
    $txt = <<<TXT
    Let's do some tests!
    http://www.google.com
    http://www.youtube.com/watch?v=L25R4DR79mU
    TXT;
    
    echo _check4Links($txt);
    ?>
    

    The output is:

    Let's do some tests!
    <a target="_blank"rel="nofollow" href="http://www.google.com">google.com</a>
    <iframe title="YouTube video player" class="youtube-player" type="text/html" width="400" height="244" src="http://www.youtube.com/embed/L25R4DR79mU" frameborder="0" allowFullScreen></iframe>