PHP 怎么PHP IPFS 上传

wen PHP项目 2

本文目录导读:

PHP 怎么PHP IPFS 上传

  1. 安装IPFS节点
  2. 使用PHP通过HTTP API上传
  3. 完整的上传示例
  4. 注意事项

我来详细介绍如何在PHP中实现IPFS上传。

安装IPFS节点

你需要在服务器上安装IPFS节点:

# 安装IPFS
wget https://dist.ipfs.io/go-ipfs/v0.12.0/go-ipfs_v0.12.0_linux-amd64.tar.gz
tar -xvzf go-ipfs_v0.12.0_linux-amd64.tar.gz
cd go-ipfs
sudo bash install.sh
# 初始化IPFS
ipfs init
# 启动IPFS daemon
ipfs daemon

使用PHP通过HTTP API上传

使用cURL直接上传

<?php
class IPFSUploader {
    private $apiUrl;
    public function __construct($apiUrl = 'http://localhost:5001') {
        $this->apiUrl = $apiUrl;
    }
    /**
     * 上传文件到IPFS
     */
    public function uploadFile($filePath) {
        if (!file_exists($filePath)) {
            throw new Exception("文件不存在: " . $filePath);
        }
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $this->apiUrl . '/api/v0/add',
            CURLOPT_POST => true,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => [
                'Content-Type: multipart/form-data'
            ],
            CURLOPT_POSTFIELDS => [
                'file' => new CURLFile($filePath)
            ]
        ]);
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if (curl_errno($ch)) {
            throw new Exception('cURL错误: ' . curl_error($ch));
        }
        curl_close($ch);
        if ($httpCode !== 200) {
            throw new Exception("HTTP错误: " . $httpCode);
        }
        return json_decode($response, true);
    }
    /**
     * 上传文本内容到IPFS
     */
    public function uploadContent($content, $filename = 'content.txt') {
        $tempFile = tempnam(sys_get_temp_dir(), 'ipfs_');
        file_put_contents($tempFile, $content);
        try {
            $result = $this->uploadFile($tempFile);
            unlink($tempFile);
            return $result;
        } catch (Exception $e) {
            unlink($tempFile);
            throw $e;
        }
    }
    /**
     * 上传JSON数据
     */
    public function uploadJSON($data) {
        $json = json_encode($data);
        return $this->uploadContent($json, 'data.json');
    }
}
// 使用示例
try {
    $ipfs = new IPFSUploader();
    // 1. 上传文件
    $result = $ipfs->uploadFile('/path/to/your/file.pdf');
    echo "文件Hash: " . $result['Hash'] . "\n";
    echo "文件名: " . $result['Name'] . "\n";
    // 2. 上传文本内容
    $result = $ipfs->uploadContent("Hello IPFS!", 'hello.txt');
    // 3. 上传JSON数据
    $data = [
        'name' => 'Test',
        'timestamp' => time()
    ];
    $result = $ipfs->uploadJSON($data);
} catch (Exception $e) {
    echo "错误: " . $e->getMessage();
}
?>

使用Guzzle HTTP客户端

<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Psr7;
use GuzzleHttp\Exception\RequestException;
class IPFSGuzzleUploader {
    private $client;
    public function __construct($apiUrl = 'http://localhost:5001') {
        $this->client = new Client([
            'base_uri' => $apiUrl,
            'timeout' => 30,
            'headers' => [
                'Content-Type' => 'multipart/form-data'
            ]
        ]);
    }
    /**
     * 上传文件
     */
    public function uploadFile($filePath) {
        try {
            $response = $this->client->post('/api/v0/add', [
                'multipart' => [
                    [
                        'name' => 'file',
                        'contents' => fopen($filePath, 'r'),
                        'filename' => basename($filePath)
                    ]
                ]
            ]);
            return json_decode($response->getBody(), true);
        } catch (RequestException $e) {
            throw new Exception("上传失败: " . $e->getMessage());
        }
    }
    /**
     * 上传目录
     */
    public function uploadDirectory($dirPath) {
        if (!is_dir($dirPath)) {
            throw new Exception("目录不存在");
        }
        $files = [];
        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($dirPath)
        );
        foreach ($iterator as $file) {
            if ($file->isFile()) {
                $relativePath = str_replace($dirPath . '/', '', $file->getPathname());
                $files[] = [
                    'name' => 'file',
                    'contents' => fopen($file->getPathname(), 'r'),
                    'filename' => $relativePath
                ];
            }
        }
        try {
            $response = $this->client->post('/api/v0/add?recursive=true&wrap-with-directory=true', [
                'multipart' => $files
            ]);
            // 解析响应(可能返回多行JSON)
            $lines = explode("\n", trim($response->getBody()));
            $results = [];
            foreach ($lines as $line) {
                if (!empty($line)) {
                    $results[] = json_decode($line, true);
                }
            }
            // 返回最后一个(目录本身)的Hash
            return end($results);
        } catch (RequestException $e) {
            throw new Exception("目录上传失败: " . $e->getMessage());
        }
    }
}
// 使用示例
$uploader = new IPFSGuzzleUploader();
try {
    // 上传单个文件
    $result = $uploader->uploadFile('document.pdf');
    echo "CID: " . $result['Hash'] . "\n";
    // 上传目录
    $result = $uploader->uploadDirectory('./my-documents');
    echo "目录CID: " . $result['Hash'] . "\n";
} catch (Exception $e) {
    echo "错误: " . $e->getMessage();
}
?>

使用PHP IPFS库

<?php
require 'vendor/autoload.php';
use Cloutier\PhpIpfsApi\IPFS;
class IPFSLibraryUploader {
    private $ipfs;
    public function __construct($host = 'localhost', $port = 5001) {
        $this->ipfs = new IPFS($host, $port);
    }
    /**
     * 上传文件
     */
    public function uploadFile($filePath) {
        $result = $this->ipfs->addFile($filePath);
        return $result;
    }
    /**
     * 上传内容
     */
    public function uploadContent($content) {
        $result = $this->ipfs->addContent($content);
        return $result;
    }
    /**
     * 从URL上传
     */
    public function uploadFromURL($url) {
        $content = file_get_contents($url);
        return $this->uploadContent($content);
    }
    /**
     * 获取文件(通过CID)
     */
    public function getFile($cid) {
        return $this->ipfs->cat($cid);
    }
}
// 安装库
// composer require cloutier/php-ipfs-api
// 使用示例
$uploader = new IPFSLibraryUploader();
try {
    // 上传文件
    $result = $uploader->uploadFile('image.jpg');
    print_r($result);
    // 上传文本
    $result = $uploader->uploadContent("Hello World!");
    // 从URL上传
    $result = $uploader->uploadFromURL('https://example.com/image.png');
} catch (Exception $e) {
    echo "错误: " . $e->getMessage();
}
?>

完整的上传示例

<?php
// upload_to_ipfs.php
class IPFSService {
    private $ipfsEndpoint;
    private $gateway;
    public function __construct($ipfsEndpoint = 'http://localhost:5001', $gateway = 'http://localhost:8080') {
        $this->ipfsEndpoint = $ipfsEndpoint;
        $this->gateway = $gateway;
    }
    /**
     * 上传并返回访问URL
     */
    public function uploadAndGetURL($filePath) {
        $result = $this->uploadToIPFS($filePath);
        if (isset($result['Hash'])) {
            return [
                'cid' => $result['Hash'],
                'url' => $this->gateway . '/ipfs/' . $result['Hash'],
                'name' => $result['Name'],
                'size' => $result['Size']
            ];
        }
        throw new Exception("上传失败");
    }
    /**
     * 批量上传文件
     */
    public function batchUpload(array $filePaths) {
        $results = [];
        foreach ($filePaths as $filePath) {
            try {
                $result = $this->uploadAndGetURL($filePath);
                $results[] = $result;
            } catch (Exception $e) {
                $results[] = [
                    'file' => $filePath,
                    'error' => $e->getMessage()
                ];
            }
        }
        return $results;
    }
    private function uploadToIPFS($filePath) {
        if (!file_exists($filePath)) {
            throw new Exception("文件不存在: " . $filePath);
        }
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $this->ipfsEndpoint . '/api/v0/add',
            CURLOPT_POST => true,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POSTFIELDS => [
                'file' => new CURLFile($filePath)
            ],
            CURLOPT_TIMEOUT => 60
        ]);
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        if ($httpCode !== 200) {
            throw new Exception("IPFS API响应错误: " . $httpCode);
        }
        return json_decode($response, true);
    }
}
// 使用示例
$ipfs = new IPFSService();
try {
    // 上传单个文件
    $result = $ipfs->uploadAndGetURL('myfile.pdf');
    echo "CID: " . $result['cid'] . "\n";
    echo "访问URL: " . $result['url'] . "\n";
    // 批量上传
    $files = [
        'file1.pdf',
        'file2.jpg',
        'file3.mp4'
    ];
    $results = $ipfs->batchUpload($files);
    print_r($results);
} catch (Exception $e) {
    echo "错误: " . $e->getMessage();
}
?>

注意事项

  1. 确保IPFS daemon在运行

    ipfs daemon
  2. CORS配置(如果需要远程访问)

    ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'
    ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "POST", "GET"]'
  3. 文件大小限制

    # 修改文件大小限制(可选)
    ipfs config --json Internal.Bitswap.MaxFileSize 104857600  # 100MB
  4. 错误处理

    • 检查文件是否存在
    • 处理网络超时
    • 验证上传结果

这些方法涵盖了PHP中IPFS上传的主要方式,可以根据你的具体需求选择适合的方案。

抱歉,评论功能暂时关闭!