Loading...

文章背景图

搭建一个随机图片API网站

2026-02-11
33
-
- 分钟
|

图床使用的是R2存储桶

首先1Panel安装PHP运行环境。
然后使用1panel创建一个静态网站,网站设置中PHP选择创建好的PHP环境。
打开网站根目录index, 编辑index.php

<?php

$accountId  = 'xxxxxxxx';
$accessKey  = 'xxxxxxxx';
$secretKey  = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$bucket     = 'your-bucket';
$prefix     = ''; # R2 图片路径
$publicHost = 'https://cusom.yourdomain.com';

$allowExt = ['jpg','jpeg','png','gif','webp'];

$host = "$accountId.r2.cloudflarestorage.com";
$endpoint = "https://$host/$bucket";

$amzDate = gmdate('Ymd\THis\Z');
$date    = gmdate('Ymd');

$queryParams = [
    'list-type' => '2',
    'prefix'    => $prefix
];
ksort($queryParams);
$query = http_build_query($queryParams, '', '&', PHP_QUERY_RFC3986);

$payloadHash = hash('sha256', '');

$canonicalHeaders =
    "host:$host\n" .
    "x-amz-content-sha256:$payloadHash\n" .
    "x-amz-date:$amzDate\n";

$signedHeaders = "host;x-amz-content-sha256;x-amz-date";

$canonicalRequest =
    "GET\n" .
    "/$bucket\n" .
    "$query\n" .
    "$canonicalHeaders\n" .
    "$signedHeaders\n" .
    $payloadHash;

$scope = "$date/auto/s3/aws4_request";

$stringToSign =
    "AWS4-HMAC-SHA256\n" .
    "$amzDate\n" .
    "$scope\n" .
    hash('sha256', $canonicalRequest);

function hmac($k, $d) {
    return hash_hmac('sha256', $d, $k, true);
}

$kDate = hmac("AWS4$secretKey", $date);
$kRegion = hmac($kDate, 'auto');
$kService = hmac($kRegion, 's3');
$kSigning = hmac($kService, 'aws4_request');

$signature = hash_hmac('sha256', $stringToSign, $kSigning);

$authorization =
    "AWS4-HMAC-SHA256 " .
    "Credential=$accessKey/$scope, " .
    "SignedHeaders=$signedHeaders, " .
    "Signature=$signature";

$ch = curl_init("$endpoint?$query");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-amz-date: $amzDate",
        "x-amz-content-sha256: $payloadHash",
        "Authorization: $authorization"
    ]
]);

$response = curl_exec($ch);
curl_close($ch);

$xml = simplexml_load_string($response);
if (!$xml || empty($xml->Contents)) {
    exit('No image');
}

$images = [];

foreach ($xml->Contents as $item) {
    $key  = (string)$item->Key;
    $size = (int)$item->Size;

    // ✅ 过滤目录占位对象
    if ($size <= 0) continue;

    $ext = strtolower(pathinfo($key, PATHINFO_EXTENSION));
    if (in_array($ext, $allowExt)) {
        $images[] = $key;
    }
}

if (!$images) {
    exit('No image');
}

$key = $images[array_rand($images)];
$url = rtrim($publicHost, '/') . '/' . $key;

// ✅ 302 跳转
header("Location: $url");
exit;

配置其中R2所需的令牌以及网址,然后就可以了。

测试下配置的随机图片API链接,随机显示成功。

文章目录