Posts to your own X profile only.
v2
2026-03-26 11:59 UTC
Requires
- php: ^8.2
Requires (Dev)
- phpstan/phpstan: ^2.1
This package is auto-updated.
Last update: 2026-03-26 12:00:05 UTC
README
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.
Requirements
- PHP 8.2 or higher
Installation
composer require codechap/x
Code Quality
This library passes PHPStan analysis at level 8 (strictest level).
./vendor/bin/phpstan analyse
Setup
All 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');
Posting Tweets
// Simple text tweet $x->post('Hello, X!'); // Reply to a tweet $x->post('This is a reply', '1234567890');
Posting with Media
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);
Threads
$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]);
Standalone Media Upload
// 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)
Tweet Actions
$x->deleteTweet('1234567890'); $x->likeTweet('1234567890'); $x->unlikeTweet('1234567890'); $x->retweet('1234567890'); $x->unretweet('1234567890');
User Lookup
// 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');
Follow / Unfollow
// 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');
Timeline
// 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
// Search recent tweets (last 7 days) $results = $x->searchTweets('php programming', 10, 'recency'); foreach ($results['tweets'] as $tweet) { echo "@{$tweet['username']}: {$tweet['text']}\n"; }
Direct Messages
// 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!');
OAuth Login Flow
// 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']
API Reference
| 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 |
Media Limits
| 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