Search code examples
phplaravel-5.1domdocumentbad-request

Laravel 5 PHP Domdocument 400 Bad request


I get a file_get_contents(https://soundcloud.com/50_cent/im-the-man-ft-sonny-digital): failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request

I want to use domdocument laravel 5.1 to get title and content id from a soundcloud url.

It worked fine with a youtube url and a vimeo url but with soundcloud it won't work.

The url I'm using is: https://soundcloud.com/50_cent/im-the-man-ft-sonny-digital just for testing.

This is my code to get the title and content id:

                $doc = new \DOMDocument();
                $doc->loadHTML(file_get_contents($input_url));
                $title = $doc->getElementsByTagName("title")->item(0)->nodeValue;

                $tags = get_meta_tags($input_url);
                $link_id = $tags['content'];
                DB::table('content_add')->insert([
                    [
                        'url' => $input_url,
                        'title' => $title,
                        'link_id'=> $link_id,
                        'type' => $type,
                        'user_id'=> Auth::id(),
                        'created_at' => Carbon::now(),
                    ],
                ]);

At the end I just add it to a database. Also when using urlencode() I get this error file_get_contents(https%3A%2F%2Fsoundcloud.com%2Fgracedmusic%2Fhello-adele): failed to open stream: No such file or directory

What am I doing wrong?


Solution

  • Maybe it will help if you create a stream context for the file_get_contents and pass the ignore_errors option set to true.

    $doc = new \DOMDocument();
    $input_url = "https://soundcloud.com/50_cent/im-the-man-ft-sonny-digital";
    $options = array(
        'http' => array(
            'ignore_errors' => true,
            'user_agent' => $_SERVER['HTTP_USER_AGENT']
        )
    );
    
    $context = stream_context_create($options);
    $doc = new \DOMDocument();
    @$doc->loadHTML(file_get_contents($input_url, false, $context));
    $title = $doc->getElementsByTagName("title")->item(0)->nodeValue;
    

    Then you can get the meta tags by checking the attributes. If you for example want the number from the 'twitter:app:url:googleplay' property:

    $link_id = '';
    $startsWith = 'soundcloud://sounds:';
    
    foreach ($doc->getElementsByTagName("meta") as $meta) {
        if ($meta->hasAttribute('property') && $meta->getAttribute('property') === 'twitter:app:url:googleplay') {
            $link_id = $meta->getAttribute('content');
            if (substr($link_id, 0, strlen($startsWith))) {
                $link_id = substr($link_id, strlen($startsWith), strlen($link_id));
                break;
            }
        }
    }