-2

I need two items in a magnet link:

magnet:?xt=urn:btih:0eb69459a28b08400c5f05bad3e63235b9853021&dn=Splinter.Cell.Blacklist-RELOADED&tr=udp%3A%2F%2Ftracker.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.istole.it%3A6969&tr=udp%3A%2F%2Ftracker.ccc.de%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337

the value of btih:

0eb69459a28b08400c5f05bad3e63235b9853021

and the value of the first udp:

udp://tracker.com:80

How to do this with PHP?

Charles
  • 50,943
  • 13
  • 104
  • 142

2 Answers2

6

As parse_url() wont help in this situation your have to use regex to parse the string, and then further manipulate the string to get the trackers. So something like:

<?php 
$string = 'magnet:?xt=urn:btih:0eb69459a28b08400c5f05bad3e63235b9853021&dn=Splinter.Cell.Blacklist-RELOADED&tr=udp%3A%2F%2Ftracker.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.istole.it%3A6969&tr=udp%3A%2F%2Ftracker.ccc.de%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337';

preg_match('#magnet:\?xt=urn:btih:(?<hash>.*?)&dn=(?<filename>.*?)&tr=(?<trackers>.*?)$#', $string, $magnet_link);

//0eb69459a28b08400c5f05bad3e63235b9853021
echo $magnet_link['hash'];

//Splinter.Cell.Blacklist-RELOADED
echo $magnet_link['filename'];

/*[trackers] => Array
(
    [0] => udp://tracker.com:80
    [1] => udp://tracker.publicbt.com:80
    [2] => udp://tracker.istole.it:6969
    [3] => udp://tracker.ccc.de:80
    [4] => udp://open.demonii.com:1337
)
*/
$magnet_link['trackers'] = explode('&', urldecode(str_replace('tr=','', $magnet_link['trackers'])));

//so to get first tracker
$magnet_link['trackers'][0];
?>
Lawrence Cherone
  • 46,049
  • 7
  • 62
  • 106
3

As recommended in the question comments, there appear to be several existing libraries for magnet links - you should probably take a look at these.

If you want to do it yourself however, one way would be to regex for the values. Let's assume that your magnet link is assigned to a variable $link like so:

$link ='magnet:?xt=urn:btih:0eb69459a28b08400c5f05bad3e63235b9853021&dn=Splinter.Cell.Blacklist-RELOADED&tr=udp%3A%2F%2Ftracker.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.istole.it%3A6969&tr=udp%3A%2F%2Ftracker.ccc.de%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337';

A quick way to get each value is to run a separate preg_match() for each value - you could combine the two regexes and run preg_match_all() but let's keep it basic. We're going to use lookbehind assertions to try and find the required values.

// your magnet link
$link = 'magnet:?xt=urn:btih:0eb69459a28b08400c5f05bad3e63235b9853021&dn=Splinter.Cell.Blacklist-RELOADED&tr=udp%3A%2F%2Ftracker.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.istole.it%3A6969&tr=udp%3A%2F%2Ftracker.ccc.de%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337';

// urls are encoded, let's reverse that
$link = urldecode($link); 

// first regex searches for 'btih:' and matches subsequent 
// word characters ([a-zA-Z0-9_])
// match(es) are captured as an array to $matchBtih
preg_match('/(?<=btih:)\w+/', $link, $matchBtih);

// same again, more or less, capturing word characters, colon and full-stop
// match(es) are captured as an array to $matchUdp
preg_match('/(?<=tr=)udp:\/\/[\w\:\.]+/', $link, $matchUdp);

// show results
var_dump($matchBtih, $matchUdp);

Should yield:

array (size=1)
  0 => string '0eb69459a28b08400c5f05bad3e63235b9853021' (length=40)
array (size=1)
  0 => string 'udp://tracker.com:80' (length=20)

Hope this helps :)

Darragh Enright
  • 13,676
  • 7
  • 41
  • 48