Installation
composer require qiniu/php-sdk
Add the package to your composer.json and run composer update.
Configuration
Create a config file (e.g., config/qiniu.php) with your Qiniu credentials:
return [
'access_key' => env('QINIU_ACCESS_KEY'),
'secret_key' => env('QINIU_SECRET_KEY'),
'bucket' => env('QINIU_BUCKET'),
'domain' => env('QINIU_DOMAIN', 'https://your-bucket.qiniu.com'),
'zone' => env('QINIU_ZONE', \Qiniu\Storage\Zone::Zone_Zone0), // Adjust based on region
];
First Use Case: Upload a File
use Qiniu\Storage\UploadManager;
use Qiniu\Auth\Auth;
$auth = new Auth(config('qiniu.access_key'), config('qiniu.secret_key'));
$uploadManager = new UploadManager();
$token = $auth->uploadToken(config('qiniu.bucket'));
$ret = $uploadManager->putFile($token, 'file-key', '/path/to/local/file');
if ($ret['key']) {
return config('qiniu.domain') . '/' . $ret['key'];
}
File Uploads
UploadManager for local files.
$ret = $uploadManager->putFile($token, 'unique-key', $localFilePath);
putFile with chunked uploads.putData with $_FILES data.
$ret = $uploadManager->putData($token, 'key', file_get_contents($_FILES['file']['tmp_name']));
File Management
Qiniu\Storage\BucketManager to list objects.
$bucketManager = new BucketManager($auth, config('qiniu.zone'));
$items = $bucketManager->listFiles(config('qiniu.bucket'));
$bucketManager->delete(config('qiniu.bucket'), 'file-key');
Signed URLs Generate temporary URLs for private files:
$auth->privateDownloadUrl('file-key', 3600); // URL expires in 1 hour
Custom Domains & CORS Configure custom domains via Qiniu console and set CORS rules in the SDK:
$bucketManager->setBucketCors(config('qiniu.bucket'), [
'allow_origins' => ['*'],
'allow_methods' => ['GET', 'HEAD'],
]);
Integration with Laravel
public function register()
{
$this->app->singleton('qiniu.auth', function () {
return new Auth(config('qiniu.access_key'), config('qiniu.secret_key'));
});
}
// QiniuServiceProvider.php
Facades\Qiniu::shouldRegister(function () {
return new QiniuService(new Auth(...));
});
public function handle(Request $request, Closure $next)
{
if ($request->hasFile('avatar')) {
$path = $request->file('avatar')->store('temp');
// Upload to Qiniu and delete temp file
}
return $next($request);
}
Batch Operations
Use putMultiFile for multiple uploads:
$ret = $uploadManager->putMultiFile($token, [
'key1' => '/path/to/file1',
'key2' => '/path/to/file2',
]);
Error Handling Wrap SDK calls in try-catch blocks:
try {
$ret = $uploadManager->putFile($token, 'key', $file);
} catch (\Exception $e) {
Log::error('Qiniu upload failed: ' . $e->getMessage());
throw new \RuntimeException('Upload failed', 500);
}
Token Expiry
File Key Conflicts
$key = 'uploads/' . Str::uuid() . '.' . $file->getClientOriginalExtension();
Zone Misconfiguration
Zone (e.g., Zone_Zone0 vs. Zone_Zone2) causes slow uploads or failures. Match your bucket’s region.Large File Timeouts
max_execution_time may timeout for large files. Increase it or use chunked uploads:
ini_set('max_execution_time', 300); // 5 minutes
CORS Issues
putPolicy includes callbackUrl:
$policy = new PutPolicy(config('qiniu.bucket'));
$policy->callbackUrl = 'https://your-domain.com/callback';
$token = $auth->uploadToken($policy);
Memory Limits
putData loads files into memory. For large files, use putFile or stream the file:
$file = fopen($localPath, 'r');
$ret = $uploadManager->putFile($token, 'key', $file);
fclose($file);
Enable Logging Set the SDK’s log level to debug:
\Qiniu\Storage\UploadManager::logLevel(\Monolog\Logger::DEBUG);
Check HTTP Status Codes
Inspect $ret['info']['statusCode'] for errors (e.g., 614 = duplicate key).
Validate Credentials Test credentials with a simple API call:
$auth->getBucketInfo(config('qiniu.bucket')); // Throws exception if invalid
Use Postman for API Testing
Manually test Qiniu’s API endpoints (e.g., http://up.qiniu.com) to isolate issues.
Custom Storage Adapter
Extend Laravel’s Filesystem to use Qiniu:
class QiniuAdapter implements FilesystemAdapter
{
public function write($path, $contents, $options = [])
{
$uploadManager = new UploadManager();
$token = $this->auth->uploadToken(config('qiniu.bucket'));
return $uploadManager->putData($token, $path, $contents);
}
// Implement other methods...
}
Event Listeners Trigger events after uploads (e.g., generate thumbnails):
event(new FileUploaded($fileUrl));
Webhook Integration Use Qiniu’s callback mechanism to process uploads asynchronously:
$policy = new PutPolicy(config('qiniu.bucket'));
$policy->callbackBody = 'filename=$(fname)&size=$(fsize)';
$policy->callbackUrl = 'https://your-domain.com/qiniu-callback';
Fallback to Local Storage Implement a hybrid storage system:
try {
$url = $this->qiniu->upload($file);
} catch (\Exception $e) {
$url = $this->localStorage->upload($file);
}
Custom Metadata Attach metadata to files during upload:
$putPolicy = new PutPolicy(config('qiniu.bucket'));
$putPolicy->persistentOps = 'avthumb/100x100/1e1';
$putPolicy->persistentNotifyUrl = 'https://your-domain.com/notify';
$token = $auth->uploadToken($putPolicy);
How can I help you explore Laravel packages today?