Decoding

Changed in version 2.0: options array is replaced with named parameters

Note

Parameter order is not guaranteed for options, use named parameters

Scalars

Scalars will be converted to their respective types:

<?php

use Arokettu\Bencode\Bencode;

$data = Bencode::decode(
    "d" .
    "3:arrli1ei2ei3ei4ee" .
    "4:booli1e" .
    "3:inti123e" .
    "6:string9:test\0test" .
    "e"
);
// [
//   "arr" => [1,2,3,4],
//   "bool" => 1,
//   "int" => 123,
//   "string" => "test\0test",
// ]

Please note that booleans will stay converted because Bencode has no native support for these types.

Lists and Dictionaries

Changed in version 3.0: Collection is now a real enum

Changed in version 4.0: Passing class names as handlers was removed

Dictionaries and lists will be arrays by default. You can change this behavior with options. Use Collection enum for built in behaviors:

<?php

use Arokettu\Bencode\Bencode;

$data = Bencode::decode(
    "...",
    // convert to a basic PHP array
    // this is a default for listType
    listType: Bencode\Collection::ARRAY,
    // convert to ArrayObject
    // this is a default for dictType
    dictType: Bencode\Collection::ARRAY_OBJECT,
    // convert to stdClass
    // dictType: Bencode\Collection::STDCLASS,
);

Or use advanced control with callbacks:

<?php

use Arokettu\Bencode\Bencode;

$data = Bencode::decode(
    "...",
    // use callback for greater flexibility
    listType: function (iterable $list) {
        return new ArrayObject(
            [...$list],
            ArrayObject::ARRAY_AS_PROPS
        );
    },
);

Big Integers

By default the library only works with a native integer type but if you need to use large integers, for example, if you want to parse a torrent file for a >= 4GB file on a 32 bit system, you can enable big integer support.

External Libraries

Added in version 1.5/2.5: GMP support

Added in version 1.6/2.6: Pear’s Math_BigInteger, brick/math

Changed in version 3.0: BigInt is now a real enum

Important

These math libraries are not explicit dependencies of this library. Install them separately before enabling.

Supported libraries:

<?php

use Arokettu\Bencode\Bencode;

// GMP
$data = Bencode::decode(
    "d3:inti79228162514264337593543950336ee",
    bigInt: Bencode\BigInt::GMP,
);
//  ['int' => gmp_init(
//      '79228162514264337593543950336'
//  )]

// brick/math
$data = Bencode::decode(
    "d3:inti79228162514264337593543950336ee",
    bigInt: Bencode\BigInt::BRICK_MATH,
);
//  ['int' => \Brick\Math\BigInteger::of(
//      '79228162514264337593543950336'
//  )]

// Math_BigInteger from PEAR
$data = Bencode::decode(
    "d3:inti79228162514264337593543950336ee",
    bigInt: Bencode\BigInt::PEAR,
);
//  ['int' => new \Math_BigInteger(
//      '79228162514264337593543950336'
//  )]

Internal Type

Added in version 1.6/2.6.

The library also has built in BigIntType. It does not require any external dependencies but also does not allow any manipulation:

<?php

use Arokettu\Bencode\Bencode;

$data = Bencode::decode(
    "d3:inti79228162514264337593543950336ee",
    bigInt: Bencode\BigInt::INTERNAL,
);
//  ['int' => new \Arokettu\Bencode\Types\BigIntType(
//      '79228162514264337593543950336'
//  )]

BigIntType is a value object with several getters:

<?php

use Arokettu\Bencode\Bencode;

// simple string representation:
$str = $data->value; // readonly property
// converters to the supported libraries:
$obj = $data->toGMP();
$obj = $data->toPear();
$obj = $data->toBrickMath();

Custom Handling

Added in version 1.6/2.6.

Changed in version 4.0: Passing class names as handlers was removed

Like listType and dictType you can use a callable:

<?php

use Arokettu\Bencode\Bencode;

$data = Bencode::decode(
    "d3:inti79228162514264337593543950336ee",
    bigInt: fn (string $value) => $value,
); // ['int' => '79228162514264337593543950336']

Working with files

Load data from a file:

<?php

use Arokettu\Bencode\Bencode;

$data = Bencode::load('testfile.torrent');

Working with streams

Added in version 1.5/2.5.

Load data from a seekable readable stream:

<?php

use Arokettu\Bencode\Bencode;

$data = Bencode::decodeStream(fopen('...', 'r'));

Decoder object

Added in version 1.7/2.7/3.0.

Decoder object can be configured on creation and used multiple times:

<?php

use Arokettu\Bencode\Decoder;

$decoder = new Decoder(bigInt: Bencode\BigInt::INTERNAL);
// all calls available:
$decoder->decode($encoded);
$decoder->decodeStream($stream);
$decoder->load($filename);