Download the PHP package unkybadtouch/qbbittorrent without Composer

On this page you can find all versions of the php package unkybadtouch/qbbittorrent. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package qbbittorrent

unkybadtouch/qbbittorrent

PHP client for the qBittorrent WebUI API v2 (5.0+), with a typed DTO layer over the raw JSON responses. UTF-8 safe, PHP 8.4 (uses property hooks).

Requirements

Install

Quick start

login() is called automatically on first request. The auth cookie is cached to cache/cookies.json (relative to the package's src/ dir) for an hour, so you don't re-authenticate on every script run; a 403 mid-session triggers one automatic re-login + retry. Call $qb->logout() to clear both the cookie and the cache file.

Core concepts

DTOs hydrate from raw API arrays. Every Client method that returns a single entity or list of entities returns Base subclasses (Blackout\Qbittorrent\DTO\*), not raw arrays. Hydration is reflection-based: public typed properties matching an array key get cast (scalars, backed enums, nested DTOs); anything else is skipped silently — a field the API doesn't return for a given call just stays uninitialized.

DTOs carry behavior. Most DTOs hold a reference to the Client that created them and expose action/mutator methods that call back into it, e.g. $torrent->pause() — no need to keep passing hashes/names back to $qb yourself.

Lazy relations. Torrent::$files/$trackers/$peers/$pieces/$webseeds are fetched on first access, not eagerly:

JSON round-trip. Every DTO implements JsonSerializable — json_encode($torrent) emits only the initialized/loaded fields (uninitialized properties and un-fetched lazy relations are omitted).

Wire conventions: booleans go over the wire as the strings 'true'/'false'. Any Client method taking a list ($hashes, $tags, $urls, ...) accepts either a bare string or an array — a single item doesn't need to be wrapped.

Usage examples

These walk through real end-to-end flows, with particular attention to nested DTOs — DTOs that hold other DTOs, either eagerly (hydrated inline from the same response) or lazily (fetched from a separate endpoint on first property access).

1. Add a magnet, poll until done, list its files

2. Nested DTOs: walking every relation on a Torrent

Torrent is the clearest nested-DTO case in the library: one hydrated object whose five collection properties are each backed by a separate API call, fetched lazily and cached per-instance.

Torrent::$downloadable_files is a computed nested-DTO filter — it reads $this->files (triggering the same lazy fetch) and drops anything with FilePriority::DO_NOT_DOWNLOAD:

3. Nested DTOs inside a plain array: the RSS feed/folder tree

Unlike Torrent's relations (DTO holding DTOs via lazy fetch), getRssFeeds() returns one eagerly hydrated structure where Feed DTOs are interleaved with plain PHP arrays (folders have no DTO of their own) at arbitrary depth:

Each Feed, however deep in the tree, still knows its own full backslash-joined path (e.g. tech\linux-distros) because Client::hydrateRssItems() threads it through the recursion during hydration — that's the one field on Feed that isn't a real API value (see the DTO reference below).

4. Two-level nested flow: search status → search results

5. RSS rules: reading and rewriting the nested torrentParams array

Rss\Rule::$torrentParams is a raw nested array (the API's modern add-torrent-options payload), and four legacy top-level properties are one-way mirrors into it:

6. Categories and torrents together

7. Serializing nested DTOs to JSON

jsonSerialize() only emits properties that are actually initialized/loaded — lazy relations you never touched are simply absent, not null:

8. Paging through the log instead of refetching everything

9. Error handling

Every network/auth failure surfaces as a plain \Exception (Guzzle exceptions are caught and rethrown, not passed through), and addTorrentUrls()/addTorrentFile() explicitly throw when qBittorrent reports zero torrents added:

DTO reference

Torrent (DTO\Torrent)

From getTorrents() / getTorrentsByCategory() / getTorrentsByHash(). The main "everything about one torrent" object.

Key fields: hash, infohash_v1, infohash_v2, name, magnet_uri, comment, state (Enum\TorrentState), progress (0–1 float), priority, size, total_size, downloaded, uploaded, dlspeed, upspeed, ratio, ratio_limit, share_limit_action (Enum\ShareLimitAction), share_limits_mode (Enum\ShareLimitsMode), num_seeds, num_leechs, eta, added_on, completion_on, category, tags (comma-separated string), save_path, download_path, tracker, dl_limit, up_limit, auto_tmm, super_seeding, seq_dl, force_start, and more — see the file for the full list (~60 fields).

Computed (not real API fields): progress_percent (float, 0–100), is_complete (bool), size_human (string, e.g. "1.2 GiB"), downloadable_files (File[], excludes files marked do-not-download).

Lazy relations: files (File[]), trackers (Tracker[]), peers (Peer[]), pieces (Piece[]), webseeds (WebSeed[]).

pause/resume are deliberately not wired onto Torrent (updating state locally would mean guessing the resulting enum value) — use $qb->stop($hash) / $qb->start($hash) and refetch if you need the new state.

Torrent\Properties (DTO\Torrent\Properties)

From getTorrentProperties($hash). A different field set from Torrent (different endpoint, /torrents/properties), not a subset — e.g. it has both is_private and private, and dl_speed_avg/up_speed_avg that Torrent lacks.

No action methods — read-only snapshot.

Torrent\File (DTO\Torrent\File)

From Torrent::$files or getTorrentFiles($hash).

Fields: index, name, size, progress, priority (Enum\FilePriority), is_seed, availability, piece_range.

Computed: progress_percent, is_complete, size_human, basename, dirname, url_path (rawurlencode'd per path segment, no host — prefix your own download host).

Torrent\Tracker (DTO\Torrent\Tracker)

From Torrent::$trackers or getTorrentTrackers($hash).

Fields: url, status (Enum\TrackerStatus), tier, num_peers, num_seeds, num_leeches, num_downloaded, msg; multi-tracker (v2) entries also carry name, updating, bt_version, next_announce, min_announce, endpoints.

No action methods — mutate via Torrent::addTrackers()/editTracker()/removeTrackers().

Torrent\Peer (DTO\Torrent\Peer)

From Torrent::$peers or getTorrentPeers($hash) (backed by /sync/torrentPeers, not /torrents/peers — the latter 404s).

Fields: ip, port, client, peer_id_client, country, country_code, progress, dl_speed, up_speed, downloaded, uploaded, connection, flags, flags_desc, relevance, files, contribution, host_name, i2p_dest.

Torrent\Piece (DTO\Torrent\Piece)

From Torrent::$pieces or getTorrentPiecesStates($hash) (the raw API returns a flat [state, state, ...] array; the client zips it into {index, state} pairs).

Fields: index, state (Enum\PieceState). Computed: is_downloaded, is_downloading.

Torrent\WebSeed (DTO\Torrent\WebSeed)

From Torrent::$webseeds or getTorrentWebSeeds($hash). One field: url. Mutate via Torrent::addWebSeeds()/editWebSeed()/removeWebSeeds().

Category (DTO\Category)

From getCategories().

Fields: name, savePath (legacy camelCase, always a string), download_path (snake_case, nullable — null for the built-in RSS category), ratio_limit, seeding_time_limit, inactive_seeding_time_limit, share_limit_action (Enum\ShareLimitAction), share_limits_mode (Enum\ShareLimitsMode).

edit() only updates name/savePath — that's all editCategory() accepts server-side; share-limit fields aren't editable through this endpoint.

Cookie (DTO\Cookie)

From getCookies(); also constructed manually for setCookies() / importCookiesJson() / importCookieHeader() / importCurlCookies() / importBrowserCookies().

Fields: name, domain, path, value, expirationDate (seconds since epoch — the setter accepts an int, a date string, or any DateTimeInterface and normalizes it).

setCookies() merges into the existing store by name+domain+path by default; pass merge: false to replace it outright.

BuildInfo (DTO\BuildInfo)

From getBuildInfo(). Flat, read-only: bitness, boost, libtorrent, openssl, platform, qt, zlib.

Transfer (DTO\Transfer)

From getTransferInfo(). Global (not per-torrent) transfer state.

Fields: connection_status, dht_nodes, dl_info_data, dl_info_speed, dl_rate_limit, up_info_data, up_info_speed, up_rate_limit, last_external_address_v4, last_external_address_v6.

Note: qBittorrent rounds a submitted byte limit to the nearest KiB server-side, but the local field is set to the exact value passed — it can drift by up to ~1023 bytes from the server until you refetch.

MainData (DTO\MainData)

From syncMainData($query) — the WebUI's polling endpoint, wraps everything in one diffable payload. Composite/untyped: rid, full_update, torrents, torrents_removed, categories, categories_removed, tags, tags_removed, trackers, trackers_removed, server_state are all raw arrays (no natural single-entity DTO home). Pass ['rid' => $lastRid] to get an incremental diff instead of the full state.

Log\Message (DTO\Log\Message)

From getLog($query) (/log/main). Fields: id, message, timestamp, type (Enum\LogMessageType — a bitmask on the wire, but each entry only ever carries one bit). Flat, no action methods. getLog() defaults to last_known_id=-1 (returns everything, capped at 20000 entries) — pass ['last_known_id' => $id] to page forward.

Log\Peer (DTO\Log\Peer)

From getPeerLog($query) (/log/peers). Fields: id, ip, timestamp, blocked, reason. Flat, no action methods.

Search\Result (DTO\Search\Result)

From Search\Status::results() or getSearchResults($id).

Fields: fileName, fileUrl, fileSize, nbSeeders, nbLeechers, engineName, siteUrl, descrLink, pubDate.

Search\Status (DTO\Search\Status)

From getSearchStatus($id). Fields: id, status (Enum\SearchStatus: RUNNING/STOPPED), total.

After delete(), don't call getSearchStatus() on that id again — the server 404s instead of returning an empty result once the id is gone.

Search\Plugin (DTO\Search\Plugin)

From getSearchPlugins(). Fields: name, fullName, url, version, enabled, supportedCategories ({id, name}[]).

Rss\Feed (DTO\Rss\Feed)

From getRssFeeds($query) — /rss/items returns a tree keyed by feed/folder name; a node with a uid key becomes a Feed, anything else is a plain nested array (no Folder DTO — recurse yourself).

Fields: path (synthesized from the node's position in the tree, not a real API field), uid, url, refreshInterval (only present when > 0). With withData=true: title, lastBuildDate, isLoading, hasError, articles.

Rss\Rule (DTO\Rss\Rule)

From getRssRules().

Fields: name (synthesized from the rule's key, not a real field), enabled, priority, useRegex, mustContain, mustNotContain, episodeFilter, affectedFeeds, lastMatch, ignoreDays, smartFilter, previouslyMatchedEpisodes, torrentParams (raw array — modern field, docs omit it). Deprecated but still-writable-through fields addPaused, torrentContentLayout, savePath, assignedCategory mirror themselves into torrentParams on every assignment (that's what the server actually reads).

Unlike other DTOs there's no per-field endpoint — only whole-object setRule — so this one gets save() instead of individual setters:

Preferences (DTO\Preferences)

From getPreferences(). Flat but huge (~220 fields covering every WebUI settings-page option: connection, BitTorrent, download paths, proxy, WebUI security, RSS, mail notifications, scheduler, etc). Generated from a live response rather than hand-typed — see the source file for the full list. Notable: share_limits_mode (Enum\ShareLimitsMode), max_ratio (float).

Read-only DTO — there's no per-field setter wired up, because the API itself has none. Push changes with the raw Client method instead, which PATCHes only the keys you pass:

Enums

All under Blackout\Qbittorrent\Enum, all backed, all use the HasLabel trait (->label() → title-cased name, e.g. TorrentState::STALLED_DL->label() → "Stalled dl").

Enum Backing Cases
TorrentState string ERROR, MISSING_FILES, DOWNLOADING, UPLOADING, STOPPED_DL, STOPPED_UP, QUEUED_DL, QUEUED_UP, STALLED_DL, STALLED_UP, CHECKING_DL, CHECKING_UP, CHECKING_RESUME_DATA, FORCED_DL, FORCED_UP, META_DL, FORCED_META_DL, MOVING, UNKNOWN
FilePriority int DO_NOT_DOWNLOAD(0), NORMAL(1), HIGH(6), MAXIMUM(7) — plus isDoNotDownload()/isNormal()/isHigh()
TrackerStatus int DISABLED(0), NOT_CONTACTED(1), WORKING(2), NOT_WORKING(4), TRACKER_ERROR(5), UNREACHABLE(6) — plus isHealthy()/isActive()
PieceState int NOT_DOWNLOADED(0), DOWNLOADING(1), DOWNLOADED(2)
LogMessageType int NORMAL(1), INFO(2), WARNING(4), CRITICAL(8)
SearchStatus string RUNNING, STOPPED
ShareLimitAction string DEFAULT, STOP, REMOVE, REMOVE_WITH_CONTENT, ENABLE_SUPER_SEEDING
ShareLimitsMode string DEFAULT, MATCH_ANY, MATCH_ALL

Client coverage

Client covers the full qBittorrent WebUI API v2 surface: auth, app (version/preferences/cookies/directory browsing), log, sync, transfer, torrents (info/add/delete/manage/trackers/peers/priority/limits/tags/ categories), rss (feeds/rules), search, and torrentcreator. Methods that return a single entity or entity list return the matching DTO above; the rest (composite/system-info endpoints with no natural single-entity shape) return raw arrays. See src/Qbittorrent/Client.php for the full method list.

Notes


All versions of qbbittorrent with dependencies

PHP Build Version
Package Version
Requires php Version >=8.4
guzzlehttp/guzzle Version ^7.0
ext-mbstring Version *
hassankhan/config Version ^3.2
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package unkybadtouch/qbbittorrent contains the following files

Loading the files please wait ...