newClass 发表于 2023-10-27 23:01

【PHP】用 alist 挂载网盘搭建图床示例

本帖最后由 newClass 于 2023-10-27 23:12 编辑

临时起意,测试是可行的,挂载网盘请看官方文档

新建index.php
<?php
if($_POST){
    include('alist.php');
    $alist = new Alist;
    $url = $alist->Api . '/d'; // 如果上传账号只授权的一个目录,这里返回的链接还需要加上该目录
    $url = $alist->Api . '/d/t9866'; // 如果上传账号只授权的一个目录,这里返回的链接还需要加上该目录
    $save_dir = '/test2/'; // 保存的目录
    $rs = $alist->get($save_dir);
    if($rs['code'] == 200){
      if($rs['data']['is_dir'] != 1){
            $alist->Mkdir($save_dir);
      }
      $rs = $alist->UpFile($_FILES['file'], $save_dir);
      // /d/t9866/test2/161536787960488ec791c57.png
      // /d/test2/161536787960488ec791c57.png
      $url_1 =$url .$save_dir . $_FILES['file']['name'] . "\n"; // 如果上传账号只授权的一个目录,这里返回的链接还需要加上该目录
      $url_2 =$url .$save_dir . $_FILES['file']['name'] . "\n"; // 如果上传账号只授权的一个目录,这里返回的链接还需要加上该目录
      echo $url_1 . "\n";
      echo $url_2 . "\n";
      echo "<img src='" . $url_1 . "'>"; // 如果文件比较大,返回的链接打开可能是502,需要刷新缓存才能显示
      echo "<img src='" . $url_2 . "'>";
      exit();
    }
    exit(json_encode($rs));
}
?>
<html>
    <head>
    <meta charset="utf-8">
    </head>
<body>

<form action="index.php" method="post" enctype="multipart/form-data">
<label for="file">上传文件:</label>
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>

</body>
</html>

创建alist.php文件,写了一部分,做图床其实 登录+上传+获取链接 就够了
<?php

Class Alist
{
    public $Api = 'https://alist.domain.com'; // 你的 alist 地址
    private $UserName = 'test'; // 账号
    private $PassWord = 'test123456'; // 密码
    private $UserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36';

    // token获取
    public function getToken(){
      $cacheName = 'alist_'.$this->UserName.'_token';
      if(is_file($cacheName)){
            return file_get_contents($cacheName);
      }
      $Url = $this->Api.'/api/auth/login';
      $Body = '{"username": "'.$this->UserName.'","password": "'.$this->PassWord.'"}';
      $Data = json_decode($this->request($Url,'POST','',$Body),1);
      if($Data['code'] == 200){
            $Token = $Data['data']['token'];
            file_put_contents($cacheName,$Token);
            return $Token;
      }else{
            exit('ERROR:'.$Data['message']);
      }
    }

    // 二选一
    public function getToken2(){
      $cacheName = 'alist_'.$this->UserName.'_token';
      if(is_file($cacheName)){
            return file_get_contents($cacheName);
      }
      $Url = $this->Api.'/api/auth/login/hash';
      $Body = '{"username": "'.$this->UserName.'","password": "'.hash('sha256',$this->PassWord.'-https://github.com/alist-org/alist').'"}';
      $Data = json_decode($this->request($Url,'POST','',$Body),1);
      if($Data['code'] == 200){
            $Token = $Data['data']['token'];
            file_put_contents($cacheName,$Token);
            return $Token;
      }else{
            exit('ERROR:'.$Data['message']);
      }
    }

    // 获取当前用户信息
    public function getUserInfo(){
      $Url = $this->Api.'/api/me';
      $Header = array(
            'Authorization:'.$this->getToken(),
      );
      $Data = json_decode($this->request($Url,'GET',$Header),1);
      return $Data;
    }

    // 新建文件夹
    public function Mkdir($dir){
      $Url = $this->Api.'/api/fs/mkdir';
      $Header = array(
            'Authorization:'.$this->getToken(),
            'Content-Type:application/json',
      );
      $Body = '{"path": "'.$dir.'"}';
      $Data = json_decode($this->request($Url,'POST',$Header,$Body),1);
      return $Data;
    }

    // 重命名文件/目录
    public function Rename($name, $path){
      $Url = $this->Api.'/api/fs/rename';
      $Header = array(
            'Authorization:'.$this->getToken(),
            'Content-Type:application/json',
      );
      $Body = '{"name": "'.$name.'","path": "'.$path.'"}';
      $Data = json_decode($this->request($Url,'POST',$Header,$Body),1);
      return $Data;
    }

    // 表单上传文件需要目录已经存在(是否存在以alist缓存为准)
    public function UpFile($file, $path){
      $Url = $this->Api.'/api/fs/form';
      $Header = array(
            'Authorization:'.$this->getToken(),
            //'Content-Length:'.$file['file']['size'],
            'Content-Type: multipart/form-data',
            'File-Path:'.urlencode($path.$file['name']),
      );
      $cfile = new CURLFile($file['tmp_name'],$file['type'],urlencode($file['name']));
      $Ch = curl_init();
      curl_setopt($Ch, CURLOPT_URL, $Url);
      curl_setopt($Ch, CURLOPT_SSL_VERIFYPEER, FALSE);
      curl_setopt($Ch, CURLOPT_SSL_VERIFYHOST, FALSE);
      curl_setopt($Ch, CURLOPT_CUSTOMREQUEST, "PUT");
      curl_setopt($Ch, CURLOPT_POSTFIELDS, array('file' => $cfile));
      curl_setopt($Ch, CURLOPT_TIMEOUT, 60);
      curl_setopt($Ch, CURLOPT_HTTPHEADER, $Header);
      curl_setopt($Ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($Ch, CURLOPT_ENCODING, 'gzip');
      $Output = curl_exec($Ch);
      curl_close($Ch);
      return json_decode($Output,1);
    }

    // POST 列出文件目录
    public function list( $path, $password='', $page='', $per_page='', $refresh='false'){
      $Url = $this->Api.'/api/fs/list';
      $Header = array(
            'Authorization:'.$this->getToken(),
      );
      $Body = '{"path": "'.$path.'","password": "'.$password.'","page": '.$page.',"per_page": '.$per_page.',"refresh": '.$refresh.'}';
      $Data = json_decode($this->request($Url,'POST',$Header,$Body),1);
      return $Data;
    }

    // POST 获取某个文件/目录信息
    public function get( $path, $password='', $page='', $per_page='', $refresh='false'){
      $Url = $this->Api.'/api/fs/get';
      $Header = array(
            'Authorization:'.$this->getToken(),
      );
      $Body = '{"path": "'.$path.'","password": "'.$password.'","page": '.$page.',"per_page": '.$per_page.',"refresh": '.$refresh.'}';
      $Data = json_decode($this->request($Url,'POST',$Header,$Body),1);
      return $Data;
    }

    private function request($Url, $Method="GET", $Header='', $Data='')
    {
      $Ch = curl_init();
      $Header = $Header ? $Header : array("Content-Type:application/json;charset=utf-8;","Accept:application/json","charset=utf-8");
      $Data = is_array($Data) ? json_encode($Data) : $Data;
      curl_setopt($Ch, CURLOPT_URL, $Url);
      curl_setopt($Ch, CURLOPT_SSL_VERIFYPEER, FALSE);
      curl_setopt($Ch, CURLOPT_SSL_VERIFYHOST, FALSE);
      if($Method == "GET"){
            curl_setopt($Ch, CURLOPT_CUSTOMREQUEST,"GET");
            curl_setopt($Ch, CURLOPT_POST, false);
            curl_setopt($Ch, CURLOPT_POSTFIELDS, $Data);
      }
      if($Method == "POST"){
            curl_setopt($Ch, CURLOPT_CUSTOMREQUEST,"POST");
            curl_setopt($Ch, CURLOPT_POST, true);
            curl_setopt($Ch, CURLOPT_POSTFIELDS, $Data);
      }
      if($Method == "PUT"){
            curl_setopt($Ch, CURLOPT_CUSTOMREQUEST, "PUT");
            curl_setopt($Ch, CURLOPT_POSTFIELDS, $Data);
      }
      if($Method == "DELETE"){
            curl_setopt($Ch, CURLOPT_CUSTOMREQUEST, "DELETE");
            curl_setopt($Ch, CURLOPT_POSTFIELDS, $Data);
      }
      if($Method == "PATCH"){
            curl_setopt($Ch, CURLOPT_CUSTOMREQUEST, "PATCH");
            curl_setopt($Ch, CURLOPT_POSTFIELDS, $Data);
      }
      curl_setopt($Ch, CURLOPT_TIMEOUT, 10);
      curl_setopt($Ch, CURLOPT_HTTPHEADER, $Header);
      curl_setopt($Ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($Ch, CURLOPT_ENCODING, 'gzip');
      $Output = curl_exec($Ch);
      curl_close($Ch);
      return $Output;
    }
}

?>

d8349565 发表于 2023-12-2 09:15

我昨天也做了类似的想法的实施,通过alist将阿里云盘做漫画的存储和分享,但是遇到了一个这样的问题:

搭建好了之后,图片可以直接访问,都正常显示,但是看过一次后,会无法加载,需要间隔一段时间才可以再次加载,主要体现如下



!(https://img.ldzfy.cn/markdown/img/202312020914171_repeat_1701479674244__507916.png)



!(https://img.ldzfy.cn/markdown/img/202312020915780_repeat_1701479701862__192894.png)

!(https://img.ldzfy.cn/markdown/img/202312020915503_repeat_1701479713573__453235.png)

看起来像是这个图片的链接是有短暂的时效性的,请问你了解是什么原因么?(我也试了下API调试获取链接,也是一样的情况)

newClass 发表于 2023-12-4 10:09

d8349565 发表于 2023-12-2 09:15
我昨天也做了类似的想法的实施,通过alist将阿里云盘做漫画的存储和分享,但是遇到了一个这样的问题:
...

经测试,alist挂载阿里云盘图片链接,似乎没有失效的情况,alist默认的缓存配置是30分钟,如果被大并发了,会有被拦截情况,但是你这个是签名过期,我这边测试都正常,你可以换号试试

阿里云盘如果是开发接口获取的链接最长有效期4小时,如果多ip并发有封号的风险;不建议你直接共享下载链接

如果确实想这么操作,可以考虑一下用天翼云盘~

参考地址:https://www.yuque.com/aliyundrive/zpfszx/gogo34oi2gy98w5d#mN50J

eenny820 发表于 2023-10-27 23:28

真好,我先保存了!

亲亲宝贝A静 发表于 2023-10-28 00:07

厉害了我的楼主{:300_970:}

fengxu 发表于 2023-10-28 06:13

顶一下!!!!

rhci 发表于 2023-10-28 09:23

虽然可能用不上,但是看见PHP,就不自觉的进来了。

逐雅斋 发表于 2023-10-28 09:26

看起来就不错,感谢分享!

Elaborate 发表于 2023-10-28 09:37

看到php 还是进来看看 感谢楼主分享{:1_893:}

四哥! 发表于 2023-10-28 10:24


看起来就不错,感谢分享!

361100 发表于 2023-10-28 10:29

看不懂 感觉很厉害

FFG 发表于 2023-10-28 10:52

看起来不错,
页: [1] 2
查看完整版本: 【PHP】用 alist 挂载网盘搭建图床示例