A PHP library for the X (formerly Twitter) API v2. Supports posting, media uploads (images, GIFs, video), threads, likes, retweets, follows, timeline, search, and direct messages.
- PHP 8.2 or higher
composer require codechap/xThis library passes PHPStan analysis at level 8 (strictest level).
./vendor/bin/phpstan analyseAll methods require OAuth 1.0a credentials from developer.x.com:
use codechap\x\X;
$x = new X();
$x->set('apiKey', 'your-api-key');
$x->set('apiKeySecret', 'your-api-key-secret');
$x->set('accessToken', 'your-access-token');
$x->set('accessTokenSecret', 'your-access-token-secret');// Simple text tweet
$x->post('Hello, X!');
// Reply to a tweet
$x->post('This is a reply', '1234567890');use codechap\x\Msg;
// Single image with alt text
$msg = new Msg();
$msg->set('content', 'Check this out!');
$msg->set('image', '/path/to/photo.jpg');
$msg->set('altText', 'A description of the image');
$x->post($msg);
// Multiple media (up to 4 images, or 1 GIF, or 1 video)
$msg = new Msg();
$msg->set('content', 'Multiple photos!');
$msg->set('media', [
['path' => '/path/to/photo1.jpg', 'alt_text' => 'First photo'],
['path' => '/path/to/photo2.png', 'alt_text' => 'Second photo'],
]);
$x->post($msg);
// Upload video
$msg = new Msg();
$msg->set('content', 'Watch this video!');
$msg->set('image', '/path/to/video.mp4');
$x->post($msg);$threadA = new Msg();
$threadA->set('content', 'Thread part 1');
$threadA->set('image', '/path/to/image.jpg');
$threadB = new Msg();
$threadB->set('content', 'Thread part 2');
$x->post([$threadA, $threadB]);// Upload media separately (returns media_id for use in tweets)
$result = $x->uploadMedia('/path/to/image.jpg', 'Alt text here');
echo $result['media_id'];
// Supported: JPEG, PNG, WebP (5MB), GIF (15MB), MP4 (512MB)$x->deleteTweet('1234567890');
$x->likeTweet('1234567890');
$x->unlikeTweet('1234567890');
$x->retweet('1234567890');
$x->unretweet('1234567890');// Get your own profile
$me = $x->me();
echo $me['data']['name'];
// Look up by username
$user = $x->lookupUser('elonmusk');
echo $user['data']['id'];
// Look up by ID
$user = $x->lookupUserById('44196397');// Accepts username or user ID
$x->followUser('@someuser');
$x->unfollowUser('someuser');
// Get followers (paginated)
$result = $x->getFollowers('someuser', 100);
foreach ($result['users'] as $user) {
echo $user['username'] . "\n";
}
// Use $result['next_token'] for next page
// Get ALL followers (auto-paginates)
$allFollowers = $x->getAllFollowers('someuser');
// Same for following
$result = $x->getFollowing('someuser');
$allFollowing = $x->getAllFollowing('someuser');// Get home timeline
$timeline = $x->getTimeline(20);
foreach ($timeline['tweets'] as $tweet) {
echo "@{$tweet['username']}: {$tweet['text']}\n";
}
// Exclude retweets and/or replies
$timeline = $x->getTimeline(20, null, 'retweets,replies');// Search recent tweets (last 7 days)
$results = $x->searchTweets('php programming', 10, 'recency');
foreach ($results['tweets'] as $tweet) {
echo "@{$tweet['username']}: {$tweet['text']}\n";
}// Get DM events
$dms = $x->getDmEvents(20);
foreach ($dms['events'] as $event) {
echo "{$event['sender_id']}: {$event['text']}\n";
}
// Send a DM
$x->sendDm('conversation-id', 'Hello there!');// Step 1: Get authorization URL
$authUrl = $x->getAuthUrlFor('http://localhost:8080/callback');
// Redirect user to $authUrl
// Step 2: Handle callback
$tokens = $x->handleCallback($oauthToken, $oauthVerifier, $callbackUrl);
// Save $tokens['access_token'] and $tokens['access_token_secret']| Method | Description |
|---|---|
me() |
Get authenticated user's profile |
lookupUser($username) |
Look up user by username |
lookupUserById($id) |
Look up user by ID |
post($message, $replyTo) |
Post tweet, thread, or reply |
deleteTweet($id) |
Delete a tweet |
likeTweet($id) |
Like a tweet |
unlikeTweet($id) |
Unlike a tweet |
retweet($id) |
Retweet |
unretweet($id) |
Undo retweet |
uploadMedia($path, $altText) |
Upload media file |
followUser($user) |
Follow a user |
unfollowUser($user) |
Unfollow a user |
getFollowers($user, $max, $token) |
Get followers (paginated) |
getFollowing($user, $max, $token) |
Get following (paginated) |
getAllFollowers($user) |
Get all followers |
getAllFollowing($user) |
Get all following |
getTimeline($max, $token, $exclude) |
Get home timeline |
searchTweets($query, $max, $sort, $token) |
Search recent tweets |
getDmEvents($max, $token) |
Get DM events |
sendDm($conversationId, $text) |
Send a direct message |
getAuthUrlFor($callback) |
Get OAuth authorization URL |
handleCallback($token, $verifier, $callback) |
Exchange OAuth tokens |
| Type | Max Size | Formats |
|---|---|---|
| Image | 5 MB | JPEG, PNG, WebP |
| Animated GIF | 15 MB | GIF |
| Video | 512 MB | MP4 |
- Max 4 images per tweet, OR 1 GIF, OR 1 video (no mixing)
- Chunked upload is used automatically for GIFs, videos, and large files