随着时代的变迁,现在的文件上传方式也越来越多了,包括传统的表单提交,还有直接通过提交文件流的方式来等。最近在研究阿里云的函数计算时想将阿里云的两大功能块——函数计算与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 发送与接收流文件