每天学习一点点,成功增加一大步

php 发送与接收流文件

PHP zhanghui 142℃

随着时代的变迁,现在的文件上传方式也越来越多了,包括传统的表单提交,还有直接通过提交文件流的方式来等。最近在研究阿里云的函数计算时想将阿里云的两大功能块——函数计算与OSS做个结合,通过函数计算做个云上传的功能将上传的文件保存到OSS(云存储)中,而函数计算只接收 Binary (二进制文件流)方式的提交。

实验涉及到的

  • sendStreamFile: 把文件以流的形式发送
  • receiveStreamFile: 接收流文件并保存到本地
  • 函数计算的部分

sendStreamFile – 把文件以流的形式发送

/** php 发送流文件
* @param  String  $url  接收的路径
* @param  String  $file 要发送的文件
* @return boolean
*/
function sendStreamFile($url, $file){
 
    if(file_exists($file)){
 
        $opts = array(
            'http' => array(
                'method' => 'POST',
                'header' => 'content-type:application/x-www-form-urlencoded',
                'content' => file_get_contents($file)
            )
        );
 
        $context = stream_context_create($opts);
        $response = file_get_contents($url, false, $context);
        $ret = json_decode($response, true);
        return $ret['success'];
 
    }else{
        return false;
    }
 
}

// 调用
$ret = sendStreamFile('接收文件流的URL','company.jpg');
var_dump($ret);

receiveStreamFile – 接收流文件并保存到本地

/**
 * php 接收流文件
 * @param  String $receiveFile 接收后保存的文件名
 * @return bool|int
 */
function receiveStreamFile($receiveFile){

    $streamData = isset($GLOBALS['HTTP_RAW_POST_DATA'])? $GLOBALS['HTTP_RAW_POST_DATA'] : '';

    if(empty($streamData)){
        $streamData = file_get_contents('php://input');
    }

    if($streamData!=''){
        $ret = file_put_contents($receiveFile, $streamData, true);
    }else{
        $ret = false;
    }

    return $ret;

}

// 调用
$receiveFile = 'receive.jpg';
$ret = receiveStreamFile($receiveFile);
echo json_encode(array('success'=>(bool)$ret));

函数计算的部分

<?php

require __DIR__ . '/vendor/autoload.php';

use RingCentral\Psr7\Response;

/*
if you open the initializer feature, please implement the initializer function, as below:
function initializer($context) {
    echo 'initializing' . PHP_EOL;
}
*/

// OSS 的基本参数
const OSS_AccessKeyId = "";
const OSS_AccessKeySecret = "";
// 经典网络
const OSS_EndPoint = "oss-cn-hangzhou.aliyuncs.com";
// 专用网络
const OSS_EndPointInternal = "oss-cn-hangzhou-internal.aliyuncs.com";
// BUCKET 名称
const OSS_BUCKET = '';

// 返回的消息模型
class ResultModel
{
    public $IsSuccess = true;
    public $Msg;
}

/**
 * 处理上传文件入 OSS 的过程
 *
 * @param string $dir_name
 * @param string $file_name
 * @param string $content
 * @return void
 */
function oss($dir_name, $file_name, $content)
{
    $object_name = $dir_name . '/' . $file_name;
    $result = new ResultModel();
    try {
        $client = new \OSS\OssClient(
            OSS_AccessKeyId,
            OSS_AccessKeySecret,
            isset($_SERVER['ali']) ? OSS_EndPointInternal : OSS_EndPoint
        );
        $res = $client->getBucketAcl(OSS_BUCKET, null);
        if (!$res == 'public-read-write') {
            $result->IsSuccess = false;
            $result->Msg = $res;
            return $result;
        } else {
            $r = $client->putObject(OSS_BUCKET, $object_name, $content);
            if ($r['info']['http_code']) {
                $result->Msg = $r['info']['url'];
                return $result;
            } else {
                $result->IsSuccess = false;
                $result->Msg = $r;
                return $result;
            }
        }
    } catch (OssException $e) {
        $result->IsSuccess = false;
        $result->Msg = $e->getMessage();
        return $result;
    }
}


function handler($request, $context): Response
{
    /*
    $body       = $request->getBody()->getContents();
    $queries    = $request->getQueryParams();
    $method     = $request->getMethod();
    $headers    = $request->getHeaders();
    $path       = $request->getAttribute('path');
    $requestURI = $request->getAttribute('requestURI');
    $clientIP   = $request->getAttribute('clientIP');
    */
    // 接收文件流
    $body = $request->getBody()->getContents();
    // 调用 OSS 的处理
    $result = oss(date('Y-m-d'), time() . '.jpg', $body);

    return new Response(
        200,
        array(),
        json_encode($result)
    );
}

转载请注明:隨習筆記 » php 发送与接收流文件

喜欢 (0)