最近有点散漫了,有点想法但是不多,不想动手,其实留的摊子还不上,每次说要去解决一下吧,就拖到不知道什么时候,这个性子不行,抽点时间这个搞一下那个也看一下的,效率也不行浪费时间倒是不少,本来这个的上传内容老早就要写的,一直拖到了今天写完。
这次主要说的一个就是一个 github 的接口调用,为了下一步的做的前端上传附件文件做基础准备,之前也说过要改办一下网站后台的上传部分,事出原因是前段时间 jsdelivr 的加速链接一直失效,导致网站页面里面的图片很多都加载不出来,为了省一点流量和cdn加速,所以吧图片的资源都放 GitHub 上了,但是这个 GitHub 有时候也抽风的,连进去官网就很慢,而且图片也不是直接给你用,所以才有了这次的这个小小的修改。
因为这次用的是改版一下网站后台的功能,所以就这个上传的功能也是用的 PHP 的方式写,本人不是后端的开发者,在实际操作的时候还是踩了坑和遇到问题的,但幸运的是我这边的功能也不是很多,新增删除修改查询基础的几样就可以满足我的需求了,可以看一下官方文档。
v3版API的文档链接
v3版API的官方教程
再开始前先把我们的GitHub 仓库地址个新建一个,不然下面都不知道往哪去新增数据了,GitHub 是一个面向开源及私有软件项目的托管平台,可以把自己的文件代码等都传上去,然后在可以使用 jsdelivr cdn 加速文件可以让其在国内访问。
新建 GitHub 仓库
去 GitHub 官网新建一个仓库
创建一个有 repo 权限的 GitHub Token
然后点击 Generate token 按钮,即可生成一个token,如下图:
新生成的 Token 只会显示一次,请妥善保存!如有遗失,重新生成即可。
下面就展开来说一下怎么去调用这些接口把文件传到GitHub上。
权限认证 Authentication
做任何接口的对接都少不了认证这一块,基本上都需要你的凭证才能给你信息,不然所有人都能无限制调用接口就乱套了,这里也是一样,针对这个凭证就是你在 GitHub 上公开仓库的 token 值。查了一下资料有很多种认证方式,我这边没做的很麻烦就是写在 header 里面,通过 Authorization: token OAUTH-TOKEN
的方式传过去就可以。
代码中可以这么写:
$header = array(
"Content-Type:application/vnd.github.v3.json",
"User-Agent:" . $options->GithubRepo,
"Authorization: token " . $options->GithubToken
);
GithubRepo
是需要传入的仓库名字, GithubToken
是需要传入的仓库 token,这样我们的请求设置就做好了。
新增文件 Create content
有了上面的 header 之后就通过 GitHub 提供的上传新建接口实现新增,在这之前需要对上传的文件进行 base64 处理,这个是文档必须的。 官方文档 。
$fileContent = file_get_contents($uploadfile);
$data = array(
"message" => "Upload file " . $fileName,
"content" => base64_encode($fileContent),
);
- 传输方法:PUT
- 访问路径:https://api.github.com/repos/用户名/仓库名/contents/文件路径
- JSON格式:
可以使用 curl 封装一个方法统一调用。
function cosCurl($url, $header, $type, $data)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $type);
if (strpos($url, 'https') !== false) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$output = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return array(
"output" => $output,
"code" => $code
);
}
// 拿到上面设置的 header 做验证信息
$result = self::cosCurl(
"https://api.github.com/repos/" . $options->GithubUser . "/" . $options->GithubRepo . "/contents" . $path_relatively,
$header,
"PUT",
$data
);
最后成功会返回一个 201 的成功的状态码,成功之后再同时写入文件到本地服务,以防链接失效可用。
更新文件 Upload content
更新文件不必新增的简单,需要先拿到文件对应的 sha 码才可以进行操作,在 GitHub 中的文件都有类似的标识就是 sha 码,拿到需要修改文件的 sha 码再对文件进行重新上传即可完成更新。
获取 sha 码也可以用到上面的公共请求方法,只不过在请求的时候不需要传入 $data 值。可以提取一个公共方法来操作,因为后面的删除也需要对文件进行获取 sha。拿到我们需要的识别码之后就可以对文件进行修改了,注意了这一步一定要在操作文件之前获取,如果code 返回 200 那就是修改成功。具体代码。
$sha = self::getGithubSha("https://api.github.com/repos/" . $options->GithubUser . "/" . $options->GithubRepo . "/contents" . $github_path);
$data = array(
"message" => "Modify file " . str_replace(self::getUploadDir(), "", $content['attachment']->path),
"content" => base64_encode($fileContent),
"sha" => $sha,
);
- 传输方法:PUT
- 访问路径:https://api.github.com/repos/用户名/仓库名/contents/文件路径
- JSON格式:
// 获取 sha
function getGithubSha($path)
{
$header = array(
"Content-Type:application/json",
"User-Agent:" . $options->GithubRepo,
"Authorization: token " . $options->GithubToken
);
$result = self::cosCurl($path, $header, "GET", array());
return json_decode($result['output'], true)['sha'];
}
删除文件 Delete content
删除文件可以修改文件差不多,唯一的区别就是需要在传入文件了,但是唯一的编码还是要加上,因为要确定是针对哪个文件进行操作。
$sha = self::getGithubSha("https://api.github.com/repos/" . $options->GithubUser . "/" . $options->GithubRepo . "/contents" . $github_path);
$data = array(
"message" => "Delete file",
"sha" => $sha,
);
按照上面两个照葫芦画瓢的操作,知道服务器返回状态码 200 就算是成功删除了。
结尾
这次是在主题的代码直接改写的,后续想做一个插件放出来,考虑在多加几个 cdn 支持,再把上传图片的压缩处理一下,上传自动压缩可能上传慢一点但是前端访问的快啊。