Laravel5.5+框架中使用GitHub API实现GitHub存储文件功能
GitHub是什么就不说了,具体我们来了解使用一下gitHub提供的GitHub API;
接口文档:
https://docs.github.com/en/rest
创建或更新文件内容接口:
https://docs.github.com/en/rest/reference/repos#create-or-update-file-contents
请求地址:
https://api.github.com/repos/{owner}/{repo}/contents/{path}
请求方式:
PUT
参数:
名称 类型 位置 描述
accept string header 建议设置为 application/vnd.github.v3+json
owner string path 用户名
repo string path 仓库名
path string path 文件存储路径
message string body 必填 - The commit message
content string body 必填 - 新文件内容,使用 Base64 编码
sha string body 如果要更新文件,则必填 - 被替换文件的 blob SHA
branch string body 分支名称 - 版本库的默认分支通常是 master
committerobjectbody提交人 - 默认为已认证的用户
author object body 文件的作者 - 默认为 committer,如省略 committer,则为认证的用户
committer 对象的属性:
名称 描述
name (string)必填 - 提交的作者或提交者的名字。如果省略 name 会收到 422 状态代码
email (string)必填 - 提交的作者或提交者的电子邮件。如果省略 email 会收到 422 状态代码
date (string)
author 对象的属性:
名称 描述
name (string)必填 - 提交的作者或提交者的名字。如果省略 name 会收到 422 状态代码
email (string)必填 - 提交的作者或提交者的电子邮件。如果省略 email 会收到 422 状态代码
date (string)
鉴权
官方提供了三种方式:
1.Basic authentication - 用户名和密码
2.OAuth2 Token - token
3.OAuth2 key/secret - client_id 和 client_secret (只支持查询)
ps:
推荐使用2方式
设置token
Settings > Developer settings > Personal access tokens > Generate new token
ps:
生成的token要妥善保存起来,只显示一次。
创建仓库
一定要把仓库设置为公开的,目的是能够使用 jsDelivr CDN 加速。
使用 GitHub 仓库作为图床,存在的问题是国内访问 GitHub 的速度很慢,可以利用 jsDelivr CDN 来加速访问。
jsDelivr 是一个免费开源的 CDN 解决方案,该平台是首个打通中国大陆与海外的免费 CDN 服务,拥有中国政府颁发的 ICP 许可证,无须担心中国防火墙问题而影响使用。
使用 jsDelivr 加速访问,需要将自定义域名设置为:
https://cdn.jsdelivr.net/gh/用户名/图床仓库名
Laravel代码
配置文件.env
GITHUB_FILE_REPOSITORY=YOUR_REPOSITORY
GITHUB_FILE_BRANCH=master
GITHUB_FILE_TOKEN=YOUR_TOKEN
GITHUB_FILE_PATH=YOUR_PATH
GITHUB_FILE_NAME=1
GITHUB_FILE_COMMIT_MESSAGE="YOUR COMMIT MESSAGE"
然后在config下创建一个配置文件:githubFile.php
<?php
return [
/**
* GitHub 仓库
*/
'repository' => env('GITHUB_FILE_REPOSITORY', ''),
/**
* 分支
*/
'branch' => env('GITHUB_FILE_BRANCH', 'master'),
/**
* Personal access token
*/
'token' => env('GITHUB_FILE_TOKEN', ''),
/**
* 存储路径,若 GitHub 仓库中没有,则自动创建
*/
'path' => env('GITHUB_FILE_PATH', ''),
/**
* 自定义域名
* 若不定义则使用 https://raw.githubusercontent.com/ 出于某些原因可能图片加载会很慢,甚至失败
* 建议使用 https://cdn.jsdelivr.net/gh/ 加速
*/
'domain' => env('GITHUB_FILE_DOMAIN', 'https://cdn.jsdelivr.net/gh/'),
/**
* 文件命名
* 1 - 以时间戳方式重命名
* 2 - 以随机字符串方式重命名
* 3 - 保持原名
* ......
*/
'name' => env('GITHUB_FILE_NAME', 1),
/**
* commit 记录
*/
'commit_message' => env('GITHUB_FILE_COMMIT_MESSAGE', ''),
];
创建一个Trait:添加上传功能
<?php
namespace App\Traits;
use Exception;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Http;
trait UploadToGithub
{
public function uploadToGithub($file, $message = '')
{
$path = config('github-file.path') . '/' . $this->setFileName($file);
$repository = config('github-file.repository');
if ($file->isValid()) {
$url = "https://api.github.com/repos/$repository/contents/$path";
$response = Http::withToken(config('github-file.token'))->put($url, [
'message' => $message ?: config('github-file.commit_message'),
'content' => base64_encode(file_get_contents($file))
]);
// 上传失败抛出一个错误,成功则返回 JSON
$body = $response->throw()->json();
// 上传成功后 GitHub API 返回的是 201,其实有了上一步这里的判断可以省略
if ($response->successful()) {
return config('github-file.domain')
? rtrim(config('github-file.domain'), '/') . '/' . trim($repository, '/') . '/' . ltrim($body['content']['path'], '/')
: $body['content']['download_url'];
}
}
throw new Exception('未发现图片');
}
/**
* 生成图片名称
* @param $file
* @return mixed|string
*/
private function setFileName($file)
{
switch (config('github-file.name')) {
case 1:
return date('YmdHis', time()) . '.' . $file->getClientOriginalExtension();
case 2:
return Str::random(32) . '.' . $file->getClientOriginalExtension();
case 3:
default:
return $file->getClientOriginalName();
}
}
}
调用上传功能
use UploadToGithub;
public function updload(Request $request)
{
$url = $this->uploadToGithub($request->file('file-field-name'));
return response()->json([
'code' => 200,
'message' => '上传成功',
'data' => [
'url' => $url
]
]);
相关文章