CLI tool
discord-php/DiscordPHP avatar
discord-php/DiscordPHP

DiscordPHP: a Discord gateway client that only runs in CLI

An API to interact with the popular messaging app Discord

1,081 stars249 forksPHPMIT

At a glance

What is it?
DiscordPHP wraps the Discord REST, gateway and voice APIs for PHP, but it is a long running CLI process rather than a web request handler, and on Windows it needs a certificate file it cannot get from the system store. The current line is version 10.
Who is it for?
DiscordPHP fits a team that already runs PHP and wants a bot that stays connected to the Discord gateway, reads events and answers in a server, and can afford to run that bot as a supervised CLI process rather than as a request handler inside a web application.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Three APIs wrapped, one process model

DiscordPHP is a wrapper for the official Discord REST, gateway and voice APIs. That is the whole of it: the library exists so that a PHP process can speak to Discord the way a Discord client does, and the three words in that sentence are the three different jobs it does.

The REST part is request and response, the ordinary HTTP API. The gateway part is the persistent websocket that delivers events, and it is the reason the library is shaped the way it is. The voice part is a separate concern, and the README points at a separate repository, DiscordPHP-Voice, for it.

The process model follows from the gateway. The FAQ is blunt about it: DiscordPHP will only run in CLI, so it cannot be dropped into an Apache or nginx request cycle. If you want an interface for your bot, the suggestion is to integrate react/http with the bot and run it through CLI. That is a real constraint on deployment, and it is the constraint that decides where a bot built on this library can live.

The documentation is published at `discord-php.github.io/DiscordPHP`, with a guide for the latest version and a class reference, and the README notes that the documentation is limited at the moment. Community tutorials live on the wiki, and there is a Discord server for questions. The library is MIT licensed with the text in `LICENSE.md`, the primary language is PHP, and the project is maintained under the Team Reflex name with the Composer package `team-reflex/discord-php`.

Install with Composer and run the example bot

The installation is a Composer requirement and an autoload include, and the README walks through it in three steps.

bash
composer require team-reflex/discord-php

That installs the latest stable release, and the development branch is available as `composer require team-reflex/discord-php dev-master`. The autoloader is then included at the top of the entry file:

php
include __DIR__.'/vendor/autoload.php';

The third step is making a bot, and the documented example is the best short introduction to the API. Trimmed from the original, it looks like this:

php
<?php

include __DIR__.'/vendor/autoload.php';

use Discord\Discord;
use Discord\WebSockets\Intents;

$discord = new Discord([
    'token' => 'bot-token',
    'intents' => Intents::getDefaultIntents()
]);

$discord->on('init', function (Discord $discord) {
    $discord->logger->info("Bot is ready!");
});

Three things are happening there. The `Discord` object is constructed with a token and a set of intents. The `init` event fires when the connection is ready. The `run()` call at the end of the original example is what keeps the process alive, and it is the line that shows why this is a CLI program.

The examples folder in the repository carries more of the same, with `ping.php`, `command.php` and `browser.php` as the sample scripts.

The Composer package name is worth noting, because it does not match the repository name. The repository is `discord-php/DiscordPHP` and the package is `team-reflex/discord-php`, and the stable and unstable versions are listed separately on Packagist.

Intents decide what the bot is allowed to see

The `intents` entry in the constructor is the first thing to understand, because it decides which events arrive at all, and it is where the Discord platform's own permissions come into the code.

The example uses `Intents::getDefaultIntents()`, and the comment next to it shows the alternative: `Intents::MESSAGE_CONTENT`, with a note that MESSAGE_CONTENT is privileged and a link to the FAQ about it. A privileged intent has to be enabled in the Discord developer portal for the application, not just in the code.

That has a direct effect on what a bot can log. The example's message handler prints the author and the content, and the comment on it states that the MESSAGE_CONTENT intent must be enabled to get the content if the bot is not mentioned or direct messaged. Without it, a bot still receives the message event, but the payload does not carry the text, which is the kind of failure that looks like a bug in the library and is actually a permission.

The lesson generalises: most of what a Discord bot cannot do comes from the portal configuration, not from PHP. The token, the intents and the privileged flags are three separate switches, and the code only sets one of them.

The event loop is the real requirement, not the API

The README is unusually direct about the knowledge a user needs. Before starting, you need to know how PHP, event loops and promises work, and the phrasing is that this is a fundamental requirement and that without it you will only suffer.

That is a fair warning for a library whose core is a persistent websocket connection, because the concurrency model is the part a user has to reason about. The chat framework in the example is not a queue and not a cron, it is a long-lived loop with callbacks, and a bot that blocks in a handler blocks the gateway.

The runtime requirements follow from that. PHP 8.1.2 or higher is required, with the latest version recommended, and the `ext-json` and `ext-zlib` extensions are required. A 32-bit x86 build additionally needs `ext-gmp`. Three extensions are recommended for a faster and more performant event loop, `ext-uv` which is the recommended one, `ext-ev` or `ext-event`, and `ext-mbstring` is recommended when non-latin characters are handled.

Memory gets its own FAQ entry, and the answer is blunt:

php
ini_set('memory_limit', '-1');

A bot that caches a lot of state in a long-lived process needs the limit removed, which is a reminder that this library is a resident process with a growing heap rather than a request that ends.

For voice there is a separate package, DiscordPHP-Voice, listed under voice requirements, which keeps the voice stack out of the core repository.

The Windows certificate trap and its silent symptom

One failure mode in the README is worth reading twice, because the symptom does not look like the cause.

PHP on Windows does not have access to the Windows Certificate Store, and TLS is used, so certificate verification is applied, and turning that off is explicitly not an option. The way you notice the problem is described in one line: the script exits immediately after one loop turn without any errors. No exception, no message, just a process that ends as soon as the gateway connection is attempted.

The fix is to download a certificate authority extract from the cURL website and set the path to that extract in `php.ini` for `openssl.cafile`. In other words, on Windows the trust store has to be provided by hand, and until it is, the connection dies silently.

The same section explains the consequence for deployment. A bot built on DiscordPHP is best run on a host where the system certificate store is available, and the Windows path is a documented workaround rather than a first-class target.

For a reader choosing a platform, this is the single most important operational fact in the README, and it is the kind of thing that is much cheaper to know before writing the bot than after.

An experimental cache, a separate voice package and a Laravel integration

Three related projects surround the core, and each has a different status.

The Cache Interface is the one to be careful with. The README puts it under a warning: the branch contains an experimental feature, do not use it in production, and the wiki page explains how to set it up. The cache sits at the heart of a gateway client, since the library has to keep state for every guild, channel, user and role it has seen, and a cache is what makes that tractable. An experimental cache is therefore a meaningful statement about how the core manages memory today, and the second FAQ entry about PHP running out of memory is the other side of the same coin.

The voice support is a separate repository, DiscordPHP-Voice, and the requirements section lists it as a voice requirement rather than something included in the main package.

The Laravel integration, laracord, is the third. The README is explicit that DiscordPHP itself is framework agnostic and designed to run directly in CLI environments, and that the framework integrations are community maintained. Laracord is a Laravel integration providing service container bindings and configuration helpers, and the README says it is maintained independently and is not part of the DiscordPHP core project.

That arrangement is coherent: the core stays framework free and process model free, and the framework glue lives with the people who use that framework.

Discord's own documentation now speaks MCP

The README has a section on getting Discord's documentation inside your editor, and it is about the Model Context Protocol rather than about PHP.

Discord serves its developer documentation as an MCP server at `https://docs.discord.com/mcp`. Connected to an editor's AI assistant, it lets the assistant search and read the current documentation, gateway events, REST routes, voice, interactions and the change log, while it works on a bot, instead of relying on what the model remembers. The server is public and read-only, with nothing to install and no sign-in or token.

It exposes three tools. `search_documentation_discord` searches the documentation. `query_docs_filesystem_documentation_discord` reads pages directly, with commands such as `tree / -L 2`, `cat /developers/topics/voice-connections.mdx` or `rg -i "seq_ack" /developers`, which is a filesystem style interface over the docs tree. And `submit_feedback` reports a page that is wrong or out of date to the documentation team.

The VS Code instructions follow, with the same steps for VS Code using `code` instead of `code-insiders`, and the note that it is Chat in agent mode that calls the tools. Each installation method adds a server named `discord-docs`.

For a library that wraps an API which changes often, this is a significant practical point. The knowledge a bot developer needs is the current gateway and REST documentation, and the project is pointing at a way to give an assistant direct access to it rather than at a set of copied reference pages that would age.

Version 10, a wide test matrix and older conversion notes

The release line is active and moves in patch steps. The recent tags are v10.67.1 from 2026-10-14, v10.67.0 from 2026-10-11 and v10.66.3 from 2026-10-06, and the last push to the repository was on 2026-10-18. The default branch is `master`, and the development branch is installable from Composer as `dev-master`.

The repository shows the shape of a long lived library. There are `src/` and `tests/` directories, `phpunit.xml` for the test runner and a `phpunit.xml.bak` beside it, `phpdoc.dist.xml` for the API documentation, and `example.env` for the environment configuration the example needs. The code style is handled by `.php-cs-fixer.dist.php` and `pint.json`, with `mago.toml` and `.phplint.yml` for further checks, and the `guide/` and `docs/` directories hold the documentation that is published to the site.

The development environment is a compose file with one service per PHP version, 8.0 through 8.4, each built from `docker/php/<version>` with the repository mounted into the container. That matrix is wider than the runtime requirement of 8.1.2 stated in the README, which is a small inconsistency between the development setup and the documented support policy, and a reason to read the requirements rather than the compose file.

The root also holds `V6_CONVERSION.md` and `V7_CONVERSION.md`, migration notes for the jump from the sixth and seventh major versions to the current one. A library at version 10 that still carries conversion notes from version 6 is a library whose users have been through several breaking changes, which is worth knowing before the next one arrives.

Editorial conclusion

DiscordPHP fits a team that already runs PHP and wants a bot that stays connected to the Discord gateway, reads events and answers in a server, and can afford to run that bot as a supervised CLI process rather than as a request handler inside a web application. It is the wrong choice for a bot that only sends scheduled messages, because a plain HTTP call to the REST API covers that case without a persistent connection, and it is a poor fit for a Windows host, where the missing certificate store has to be worked around with a downloaded CA extract. Before adopting it, confirm that the target host is not Windows, install one of the event loop extensions rather than relying on the default, read the requirements in the README about the 8.1.2 floor and the privileged MESSAGE_CONTENT intent, and keep the experimental Cache Interface out of production as the README warns.

Frequently asked questions

Can I run DiscordPHP on a web server such as Apache or nginx?

No, DiscordPHP will only run in CLI. The FAQ suggests integrating react/http with your bot and running it through CLI if you want an interface for the bot.

What PHP version and extensions does DiscordPHP require?

PHP 8.1.2 or higher, with ext-json and ext-zlib required, and ext-gmp needed on 32-bit x86 builds. One of ext-uv, ext-ev or ext-event is recommended for a faster event loop, ext-mbstring is recommended for non-latin characters, and voice support comes from the separate DiscordPHP-Voice package.

Why does my DiscordPHP script exit immediately on Windows?

PHP on Windows cannot reach the Windows Certificate Store, so TLS certificate verification fails, and the symptom is a script that exits right after one loop turn without errors. Download a certificate authority extract from the cURL site and set its path as openssl.cafile in php.ini.

What is the Cache Interface in DiscordPHP?

It is an experimental feature on a branch that the README marks as not for production use, with setup instructions on the project wiki page. The core library manages state for the guilds, channels, users and roles it has seen without it.

Official sources

  1. discord-php/DiscordPHP on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/discord-php-discordphp.svg)](https://hysenlabs.com/projects/discord-php-discordphp)

Was this useful?