First commit

This commit is contained in:
2025-10-02 10:33:06 +08:00
parent 198b8bf2a6
commit c38eed4a22
5512 changed files with 958855 additions and 0 deletions

12
app/Common/extend/qiniu/.gitignore vendored Executable file
View File

@@ -0,0 +1,12 @@
*.phar
*.zip
build/artifacts
phpunit.xml
phpunit.functional.xml
.DS_Store
.swp
.build
composer.lock
vendor
src/package.xml
.idea/

View File

@@ -0,0 +1,35 @@
filter:
excluded_paths: [tests/*]
checks:
php:
code_rating: true
remove_extra_empty_lines: true
remove_php_closing_tag: true
remove_trailing_whitespace: true
fix_use_statements:
remove_unused: true
preserve_multiple: false
preserve_blanklines: true
order_alphabetically: true
fix_php_opening_tag: true
fix_linefeed: true
fix_line_ending: true
fix_identation_4spaces: true
fix_doc_comments: true
tools:
external_code_coverage:
timeout: 1200
runs: 3
php_analyzer: true
php_code_coverage: false
php_code_sniffer:
config:
standard: PSR2
filter:
paths: ['src']
php_loc:
enabled: true
excluded_dirs: [vendor, tests]
php_cpd:
enabled: true
excluded_dirs: [vendor, tests]

View File

@@ -0,0 +1,23 @@
sudo: false
language: php
php:
- 5.4
- 5.5
- 5.6
- 7.0
before_script:
- export QINIU_TEST_ENV="travis"
- travis_retry composer self-update
- travis_retry composer install --no-interaction --prefer-source --dev
script:
- ./vendor/bin/phpcs --standard=PSR2 src
- ./vendor/bin/phpcs --standard=PSR2 examples
- ./vendor/bin/phpcs --standard=PSR2 tests
- ./vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover tests/Qiniu/Tests/
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover

View File

@@ -0,0 +1,105 @@
# Changelog
## 7.2.7 (2018-11-06)
* 添加 QVM 内网上传到 KODO 的 zone 设置
## 7.2.6 (2018-05-18)
* 修复rsrsf在不同机房默认的https域名
## 7.2.5 (2018-05-10)
* 修复表单上传中多余的参数checkCrc导致的fname错位问题
## 7.2.4 (2018-05-09)
### 增加
* 连麦功能
## 7.2.3 (2018-01-20)
### 增加
* 新加坡机房
### 修正
* 获取域名的入口域名
* http回复头部兼容大小写
## 7.2.2 (2017-11-06)
### 增加
* Qiniu算法的鉴权方法
## 7.1.4 (2017-06-21)
### 增加
* cdn 文件/目录 刷新
* cdn 获取 流量/带宽
* cdn 获取域名的访问日志列表
* cdn 对资源链接进行时间戳防盗链签名
## 7.1.3 (2016-11-18)
### 增加
* move, copy操作增加force参数
## 7.1.2 (2016-11-12)
### 修正
* 明确抛出获取各区域域名失败时的报错
## 7.1.1 (2016-11-02)
### 修正
* 多区域配置文件存储目录从home修改到tmp目录
## 7.1.0 (2016-10-22)
### 增加
* 多存储区域的支持
## 7.0.8 (2016-07-19)
### 增加
* demo
* https url 支持
* deleteAfterDays 策略
* 添加图片处理链接统一拼接方法 by @SherlockRen
## 7.0.7 (2016-01-12)
### 修正
* PersistentFop参数pipeline和notify_url失效
* resume 模式 close file inputstream
## 7.0.6 (2015-12-05)
### 修正
* php7.0 Json 对空字符串解析单元测试报错
* 开启安全模式或者设置可操作目录树时设置CURLOPT_FOLLOWLOCATION报错, by @twocabbages
* fetch 支持不指定key, by @sinkcup
## 7.0.5 (2015-10-29)
### 增加
* 增加上传策略最小文件大小限制 fsizeMin
* 增加常见examples
## 7.0.4 (2015-07-23)
### 修正
* 一些地方的严格比较检查
* resumeupload 备用地址失效
## 7.0.3 (2015-07-10)
### 修改
* 多zone 支持
## 7.0.2 (2015-04-18)
### 修改
* fetch 接口返回内容调整
* pfop 接口调整
###修正
* exception 类调用
## 7.0.1 (2015-03-27)
### 增加
* 增加代码注释
## 7.0.0 (2015-02-03)
### 增加
* 简化上传接口
* 自动选择断点续上传还是直传
* 重构代码,接口和内部结构更清晰
* 改变mime
* 代码覆盖度报告
* policy改为array, 便于灵活增加,并加入过期字段检查
* 文件列表支持目录形式
* 利用元编程方式支持 fop 和 pfop

View File

@@ -0,0 +1,30 @@
# 贡献代码指南
我们非常欢迎大家来贡献代码,我们会向贡献者致以最诚挚的敬意。
一般可以通过在Github上提交[Pull Request](https://github.com/qiniu/php-sdk)来贡献代码。
## Pull Request要求
- **[PSR-2 编码风格标准](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** 。要通过项目中的code sniffer检查。
- **代码格式** 提交前 请按 ./vendor/bin/phpcbf --standard=PSR2 进行格式化。
- **必须添加测试!** - 如果没有测试(单元测试、集成测试都可以),那么提交的补丁是不会通过的。
- **记得更新文档** - 保证`README.md`以及其他相关文档及时更新,和代码的变更保持一致性。
- **考虑我们的发布周期** - 我们的版本号会服从[SemVer v2.0.0](http://semver.org/)我们绝对不会随意变更对外的API。
- **创建feature分支** - 最好不要从你的master分支提交 pull request。
- **一个feature提交一个pull请求** - 如果你的代码变更了多个操作那就提交多个pull请求吧。
- **清晰的commit历史** - 保证你的pull请求的每次commit操作都是有意义的。如果你开发中需要执行多次的即时commit操作那么请把它们放到一起再提交pull请求。
## 运行测试
``` bash
./vendor/bin/phpunit tests/Qiniu/Tests/
```

22
app/Common/extend/qiniu/LICENSE Executable file
View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2014 Qiniu, Ltd.<sdk@qiniu.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,75 @@
# Qiniu Cloud SDK for PHP
[![doxygen.io](http://doxygen.io/github.com/qiniu/php-sdk/?status.svg)](http://doxygen.io/github.com/qiniu/php-sdk/)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE)
[![Build Status](https://travis-ci.org/qiniu/php-sdk.svg)](https://travis-ci.org/qiniu/php-sdk)
[![Latest Stable Version](https://img.shields.io/packagist/v/qiniu/php-sdk.svg)](https://packagist.org/packages/qiniu/php-sdk)
[![Total Downloads](https://img.shields.io/packagist/dt/qiniu/php-sdk.svg)](https://packagist.org/packages/qiniu/php-sdk)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/qiniu/php-sdk/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/qiniu/php-sdk/?branch=master)
[![Code Coverage](https://scrutinizer-ci.com/g/qiniu/php-sdk/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/qiniu/php-sdk/?branch=master)
[![Join Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/qiniu/php-sdk?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![@qiniu on weibo](http://img.shields.io/badge/weibo-%40qiniutek-blue.svg)](http://weibo.com/qiniutek)
## 安装
* 通过composer这是推荐的方式可以使用composer.json 声明依赖或者运行下面的命令。SDK 包已经放到这里 [`qiniu/php-sdk`][install-packagist] 。
```bash
$ composer require qiniu/php-sdk
```
* 直接下载安装SDK 没有依赖其他第三方库,但需要参照 composer的autoloader增加一个自己的autoloader程序。
## 运行环境
| Qiniu SDK版本 | PHP 版本 |
|:--------------------:|:---------------------------:|
| 7.x | cURL extension, 5.3 - 5.6,7.0 |
| 6.x | cURL extension, 5.2 - 5.6 |
## 使用方法
### 上传
```php
use Qiniu\Storage\UploadManager;
use Qiniu\Auth;
...
$upManager = new UploadManager();
$auth = new Auth($accessKey, $secretKey);
$token = $auth->uploadToken($bucketName);
list($ret, $error) = $upManager->put($token, 'formput', 'hello world');
...
```
## 测试
``` bash
$ ./vendor/bin/phpunit tests/Qiniu/Tests/
```
## 常见问题
- $error保留了请求响应的信息失败情况下ret 为none, 将$error可以打印出来提交给我们。
- API 的使用 demo 可以参考 [单元测试](https://github.com/qiniu/php-sdk/blob/master/tests)。
## 代码贡献
详情参考[代码提交指南](https://github.com/qiniu/php-sdk/blob/master/CONTRIBUTING.md)。
## 贡献记录
- [所有贡献者](https://github.com/qiniu/php-sdk/contributors)
## 联系我们
- 如果需要帮助请提交工单在portal右侧点击咨询和建议提交工单或者直接向 support@qiniu.com 发送邮件)
- 如果有什么问题,可以到问答社区提问,[问答社区](http://qiniu.segmentfault.com/)
- 更详细的文档,见[官方文档站](http://developer.qiniu.com/)
- 如果发现了bug 欢迎提交 [issue](https://github.com/qiniu/php-sdk/issues)
- 如果有功能需求,欢迎提交 [issue](https://github.com/qiniu/php-sdk/issues)
- 如果要提交代码,欢迎提交 pull request
- 欢迎关注我们的[微信](http://www.qiniu.com/#weixin) [微博](http://weibo.com/qiniutek),及时获取动态信息。
## 代码许可
The MIT License (MIT).详情见 [License文件](https://github.com/qiniu/php-sdk/blob/master/LICENSE).
[packagist]: http://packagist.org
[install-packagist]: https://packagist.org/packages/qiniu/php-sdk

View File

@@ -0,0 +1,14 @@
<?php
function classLoader($class)
{
$path = str_replace('\\', DIRECTORY_SEPARATOR, $class);
$file = __DIR__ . '/src/' . $path . '.php';
if (file_exists($file)) {
require_once $file;
}
}
spl_autoload_register('classLoader');
require_once __DIR__ . '/src/Qiniu/functions.php';

View File

@@ -0,0 +1,26 @@
{
"name": "qiniu/php-sdk",
"type": "library",
"description": "Qiniu Resource (Cloud) Storage SDK for PHP",
"keywords": ["qiniu", "storage", "sdk", "cloud"],
"homepage": "http://developer.qiniu.com/",
"license": "MIT",
"authors": [
{
"name": "Qiniu",
"email": "sdk@qiniu.com",
"homepage": "http://www.qiniu.com"
}
],
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"squizlabs/php_codesniffer": "~2.3"
},
"autoload": {
"psr-4": {"Qiniu\\": "src/Qiniu"},
"files": ["src/Qiniu/functions.php"]
}
}

View File

@@ -0,0 +1,71 @@
# Rtc Streaming Cloud Server-Side Library For PHP
## Features
- Appclient
- [x] 创建房间: client->createApp()
- [x] 查看房间: client->getApp()
- [x] 删除房间: client->deleteApp()
- [x] 生成房间token: client->appToken()
## Contents
- [Installation](#installation)
- [Usage](#usage)
- [Configuration](#configuration)
- [App](#app)
- [Create a app](#create-a-app)
- [Get a app](#get-a-app)
- [Delete a app](#delete-a-app)
- [Generate a app token](#generate-a-app-token)
## Usage
### App
#### Create a app
```php
$ak = "gwd_gV4gPKZZsmEOvAuNU1AcumicmuHooTfu64q5";
$sk = "xxxx";
$auth = new Auth($ak, $sk);
$client = new Qiniu\Rtc\AppClient($auth);
$resp=$client->createApp("901","testApp");
print_r($resp);
```
#### Get an app
```php
$ak = "gwd_gV4gPKZZsmEOvAuNU1AcumicmuHooTfu64q5";
$sk = "xxxx";
$auth = new Auth($ak, $sk);
$client = new Qiniu\Rtc\AppClient($auth);
$resp=$client->getApp("deq02uhb6");
print_r($resp);
```
#### Delete an app
```php
$ak = "gwd_gV4gPKZZsmEOvAuNU1AcumicmuHooTfu64q5";
$sk = "xxxx";
$auth = new Auth($ak, $sk);
$client = new Qiniu\Rtc\AppClient($auth);
$resp=$client->deleteApp("deq02uhb6");
print_r($resp);
```
#### Generate an app token
```php
$ak = "gwd_gV4gPKZZsmEOvAuNU1AcumicmuHooTfu64q5";
$sk = "xxxx";
$auth = new Auth($ak, $sk);
$client = new Qiniu\Rtc\AppClient($auth);
$resp=$client->appToken("deq02uhb6", "lfx", '1111', (time()+3600), 'user');
print_r($resp);
```

View File

@@ -0,0 +1,42 @@
<?php
require_once("../../autoload.php");
use \Qiniu\Auth;
$ak = 'gwd_gV4gPKZZsmEOvAuNU1AcumicmuHooTfu64q5';
$sk = 'xxxx';
$auth = new Auth($ak, $sk);
$client = new Qiniu\Rtc\AppClient($auth);
$hub = 'lfxlive';
$title = 'lfxl';
try {
//创建app
$resp = $client->createApp($hub, $title, $maxUsers);
print_r($resp);
// 获取app状态
$resp = $client->getApp('dgdl5ge8y');
print_r($resp);
//修改app状态
$mergePublishRtmp = null;
$mergePublishRtmp['enable'] = true;
$resp = $client->updateApp('dgdl5ge8y', $hub, $title, $maxUsers, $mergePublishRtmp);
print_r($resp);
//删除app
$resp = $client->deleteApp('dgdl5ge8y');
print_r($resp);
//获取房间连麦的成员
$resp=$client->listUser("dgbfvvzid", 'lfxl');
print_r($resp);
//剔除房间的连麦成员
$resp=$client->kickUser("dgbfvvzid", 'lfx', "qiniu-f6e07b78-4dc8-45fb-a701-a9e158abb8e6");
print_r($resp);
// 列举房间
$resp=$client->listActiveRooms("dgbfvvzid", 'lfx', null, null);
print_r($resp);
//鉴权的有效时间: 1个小时.
$resp = $client->appToken("dgd4vecde", "lfxl", '1111', (time()+3600), 'user');
print_r($resp);
} catch (\Exception $e) {
echo "Error:", $e, "\n";
}

View File

@@ -0,0 +1,10 @@
# examples
这些 examples 旨在帮助你快速了解使用七牛的sdk。这些demo都是可以直接运行的 但是在运行之前需要填上您自己的参数。
比如:
* `$bucket` 需要填上您想操作的 [bucket名字](http://developer.qiniu.com/docs/v6/api/overview/concepts.html#bucket)。
* `$accessKey``$secretKey` 可以在我们的[管理后台](https://portal.qiniu.com/setting/key)找到。
* 在进行`视频转码` `压缩文件`等异步操作时 需要使用到的队列名称也可以在我们[管理后台](https://portal.qiniu.com/mps/pipeline)新建。

View File

@@ -0,0 +1,40 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Cdn\CdnManager;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$auth = new Qiniu\Auth($accessKey, $secretKey);
$cdnManager = new CdnManager($auth);
//获取流量和带宽数据
//参考文档http://developer.qiniu.com/article/fusion/api/traffic-bandwidth.html
$domains = array(
"javasdk.qiniudn.com",
"phpsdk.qiniudn.com"
);
$startDate = "2017-08-20";
$endDate = "2017-08-21";
//5min or hour or day
$granularity = "day";
//获取带宽数据
list($bandwidthData, $getBandwidthErr) = $cdnManager->getBandwidthData(
$domains,
$startDate,
$endDate,
$granularity
);
if ($getBandwidthErr != null) {
var_dump($getBandwidthErr);
} else {
echo "get bandwidth data success\n";
print_r($bandwidthData);
}

View File

@@ -0,0 +1,34 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Cdn\CdnManager;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$auth = new Qiniu\Auth($accessKey, $secretKey);
$cdnManager = new CdnManager($auth);
//获取流量和带宽数据
//参考文档http://developer.qiniu.com/article/fusion/api/traffic-bandwidth.html
$domains = array(
"javasdk.qiniudn.com",
"phpsdk.qiniudn.com"
);
$startDate = "2017-08-20";
$endDate = "2017-08-21";
//5min or hour or day
$granularity = "day";
//获取流量数据
list($fluxData, $getFluxErr) = $cdnManager->getFluxData($domains, $startDate, $endDate, $granularity);
if ($getFluxErr != null) {
var_dump($getFluxErr);
} else {
echo "get flux data success\n";
print_r($fluxData);
}

View File

@@ -0,0 +1,29 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Cdn\CdnManager;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$auth = new Qiniu\Auth($accessKey, $secretKey);
$cdnManager = new CdnManager($auth);
$domains = array(
"javasdk.qiniudn.com",
"phpsdk.qiniudn.com"
);
$logDate = '2017-08-20';
//获取日志下载链接
//参考文档http://developer.qiniu.com/article/fusion/api/log.html
list($logListData, $getLogErr) = $cdnManager->getCdnLogList($domains, $logDate);
if ($getLogErr != null) {
var_dump($getLogErr);
} else {
echo "get cdn log list success\n";
print_r($logListData);
}

View File

@@ -0,0 +1,52 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Cdn\CdnManager;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$auth = new Qiniu\Auth($accessKey, $secretKey);
//待刷新的文件列表和目录文件列表最多一次100个目录最多一次10个
//参考文档http://developer.qiniu.com/article/fusion/api/refresh.html
$urls = array(
"http://phpsdk.qiniudn.com/qiniu.jpg",
"http://phpsdk.qiniudn.com/qiniu2.jpg",
);
//刷新目录需要联系七牛技术支持开通账户权限
$dirs = array(
"http://phpsdk.qiniudn.com/test/"
);
$cdnManager = new CdnManager($auth);
// 目前客户默认没有目录刷新权限刷新会有400038报错参考https://developer.qiniu.com/fusion/api/1229/cache-refresh
// 需要刷新目录请工单联系技术支持 https://support.qiniu.com/tickets/category
list($refreshResult, $refreshErr) = $cdnManager->refreshUrlsAndDirs($urls, $dirs);
if ($refreshErr != null) {
var_dump($refreshErr);
} else {
echo "refresh request sent\n";
print_r($refreshResult);
}
//如果只有刷新链接或者目录的需求,可以分布使用
list($refreshResult, $refreshErr) = $cdnManager->refreshUrls($urls);
if ($refreshErr != null) {
var_dump($refreshErr);
} else {
echo "refresh request sent\n";
print_r($refreshResult);
}
list($refreshResult, $refreshErr) = $cdnManager->refreshDirs($dirs);
if ($refreshErr != null) {
var_dump($refreshErr);
} else {
echo "refresh request sent\n";
print_r($refreshResult);
}

View File

@@ -0,0 +1,19 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Cdn\CdnManager;
//创建时间戳防盗链
//时间戳防盗链密钥,后台获取
$encryptKey = 'your_domain_timestamp_antileech_encryptkey';
//带访问协议的域名
$url1 = 'http://phpsdk.qiniuts.com/24.jpg?avinfo';
$url2 = 'http://phpsdk.qiniuts.com/24.jpg';
//有效期时间(单位秒)
$durationInSeconds = 3600;
$signedUrl = CdnManager::createTimestampAntiLeechUrl($url1, $encryptKey, $durationInSeconds);
print($signedUrl);

View File

@@ -0,0 +1,74 @@
<?php
require_once __DIR__ . '/../autoload.php';
// 引入图片处理类
use Qiniu\Processing\ImageUrlBuilder;
$imageUrlBuilder = new ImageUrlBuilder();
// 要处理图片
$url = 'http://78re52.com1.z0.glb.clouddn.com/resource/gogopher.jpg';
$url2 = 'http://78re52.com1.z0.glb.clouddn.com/resource/gogopher.jpg?watermark/1/gravity/SouthEast/dx/0/dy/0/image/'
. 'aHR0cDovL2Fkcy1jZG4uY2h1Y2h1amllLmNvbS9Ga1R6bnpIY2RLdmRBUFc5cHZZZ3pTc21UY0tB';
$waterImage = 'http://developer.qiniu.com/resource/logo-2.jpg';
/**
* 缩略图链接拼接
*
* @param string $url 图片链接
* @param int $mode 缩略模式
* @param int $width 宽度
* @param int $height 长度
* @param string $format 输出类型 [可选]
* @param int $quality 图片质量 [可选]
* @param int $interlace 是否支持渐进显示 [可选]
* @param int $ignoreError 忽略结果 [可选]
* @return string
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/imageview2.html
* @author Sherlock Ren <sherlock_ren@icloud.com>
*/
$thumbLink = $imageUrlBuilder->thumbnail($url, 1, 100, 100);
// 函数方式调用 也可拼接多个操作参数 图片+水印
$thumbLink2 = \Qiniu\thumbnail($url2, 1, 100, 100);
var_dump($thumbLink, $thumbLink2);
/**
* 图片水印
*
* @param string $url 图片链接
* @param string $image 水印图片链接
* @param numeric $dissolve 透明度 [可选]
* @param string $gravity 水印位置 [可选]
* @param numeric $dx 横轴边距 [可选]
* @param numeric $dy 纵轴边距 [可选]
* @param numeric $watermarkScale 自适应原图的短边比例 [可选]
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html
* @return string
* @author Sherlock Ren <sherlock_ren@icloud.com>
*/
$waterLink = $imageUrlBuilder->waterImg($url, $waterImage);
// 函数调用方法
//$waterLink = \Qiniu\waterImg($url, $waterImage);
var_dump($waterLink);
/**
* 文字水印
*
* @param string $url 图片链接
* @param string $text 文字
* @param string $font 文字字体
* @param string $fontSize 文字字号
* @param string $fontColor 文字颜色 [可选]
* @param numeric $dissolve 透明度 [可选]
* @param string $gravity 水印位置 [可选]
* @param numeric $dx 横轴边距 [可选]
* @param numeric $dy 纵轴边距 [可选]
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html#text-watermark
* @return string
* @author Sherlock Ren <sherlock_ren@icloud.com>
*/
$textLink = $imageUrlBuilder->waterText($url, '你瞅啥', '微软雅黑', 300);
// 函数调用方法
// $textLink = \Qiniu\waterText($url, '你瞅啥', '微软雅黑', 300);
var_dump($textLink);

View File

@@ -0,0 +1,19 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
use Qiniu\Processing\PersistentFop;
$accessKey = 'Access_Key';
$secretKey = 'Secret_Key';
$auth = new Auth($accessKey, $secretKey);
// 要转码的文件所在的空间。
$bucket = 'Bucket_Name';
// 转码是使用的队列名称。 https://portal.qiniu.com/mps/pipeline
$pipeline = 'pipeline_name';
// 初始化
$pfop = new PersistentFop($auth, $bucket, $pipeline);

View File

@@ -0,0 +1,18 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Processing\PersistentFop;
$pfop = new Qiniu\Processing\PersistentFop(null, null);
// 触发持久化处理后返回的 Id
$persistentId = 'z1.5b8a48e5856db843bc24cfc3';
// 通过persistentId查询该 触发持久化处理的状态
list($ret, $err) = $pfop->status($persistentId);
if ($err) {
print_r($err);
} else {
print_r($ret);
}

View File

@@ -0,0 +1,43 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
use Qiniu\Processing\PersistentFop;
// 去我们的portal 后台来获取AK, SK
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$key = 'qiniu.png';
$auth = new Auth($accessKey, $secretKey);
// 异步任务的队列, 去后台新建: https://portal.qiniu.com/mps/pipeline
$pipeline = 'sdktest';
$pfop = new PersistentFop($auth, null);
// 进行zip压缩的url
$url1 = 'http://phpsdk.qiniudn.com/php-logo.png';
$url2 = 'http://phpsdk.qiniudn.com/1.png';
//压缩后的key
$zipKey = 'test.zip';
$fops = 'mkzip/2/url/' . \Qiniu\base64_urlSafeEncode($url1);
$fops .= '/url/' . \Qiniu\base64_urlSafeEncode($url2);
$fops .= '|saveas/' . \Qiniu\base64_urlSafeEncode("$bucket:$zipKey");
$notify_url = null;
$force = false;
list($id, $err) = $pfop->execute($bucket, $key, $fops, $pipeline, $notify_url, $force);
echo "\n====> pfop mkzip result: \n";
if ($err != null) {
var_dump($err);
} else {
echo "PersistentFop Id: $id\n";
$res = "http://api.qiniu.com/status/get/prefop?id=$id";
echo "Processing result: $res";
}

View File

@@ -0,0 +1,46 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
use Qiniu\Processing\PersistentFop;
//对已经上传到七牛的视频发起异步转码操作
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
//要转码的文件所在的空间和文件名。
$key = 'qiniu.mp4';
//转码是使用的队列名称。 https://portal.qiniu.com/mps/pipeline
$pipeline = 'sdktest';
//转码完成后通知到你的业务服务器。
$notifyUrl = 'http://375dec79.ngrok.com/notify.php';
$force = false;
$config = new \Qiniu\Config();
$config->useHTTPS = true;
$pfop = new PersistentFop($auth, $config);
//要进行视频截图操作
$fops = "vframe/jpg/offset/1/w/480/h/360/rotate/90|saveas/" .
\Qiniu\base64_urlSafeEncode($bucket . ":qiniu_480x360.jpg");
list($id, $err) = $pfop->execute($bucket, $key, $fops, $pipeline, $notifyUrl, $force);
echo "\n====> pfop avthumb result: \n";
if ($err != null) {
var_dump($err);
} else {
echo "PersistentFop Id: $id\n";
}
//查询转码的进度和状态
list($ret, $err) = $pfop->status($id);
echo "\n====> pfop avthumb status: \n";
if ($err != null) {
var_dump($err);
} else {
var_dump($ret);
}

View File

@@ -0,0 +1,47 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
use Qiniu\Processing\PersistentFop;
//对已经上传到七牛的视频发起异步转码操作
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
//要转码的文件所在的空间和文件名。
$key = 'qiniu.mp4';
//转码是使用的队列名称。 https://portal.qiniu.com/mps/pipeline
$pipeline = 'sdktest';
$force = false;
//转码完成后通知到你的业务服务器。
$notifyUrl = 'http://375dec79.ngrok.com/notify.php';
$config = new \Qiniu\Config();
//$config->useHTTPS=true;
$pfop = new PersistentFop($auth, $config);
//要进行转码的转码操作。 http://developer.qiniu.com/docs/v6/api/reference/fop/av/avthumb.html
$fops = "avthumb/mp4/s/640x360/vb/1.4m|saveas/" . \Qiniu\base64_urlSafeEncode($bucket . ":qiniu_640x360.mp4");
list($id, $err) = $pfop->execute($bucket, $key, $fops, $pipeline, $notifyUrl, $force);
echo "\n====> pfop avthumb result: \n";
if ($err != null) {
var_dump($err);
} else {
echo "PersistentFop Id: $id\n";
}
//查询转码的进度和状态
list($ret, $err) = $pfop->status($id);
echo "\n====> pfop avthumb status: \n";
if ($err != null) {
var_dump($err);
} else {
var_dump($ret);
}

View File

@@ -0,0 +1,52 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
use Qiniu\Processing\PersistentFop;
//对已经上传到七牛的视频发起异步转码操作
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
//要转码的文件所在的空间和文件名。
$key = 'qiniu.mp4';
//转码是使用的队列名称。 https://portal.qiniu.com/mps/pipeline
$pipeline = 'sdktest';
//转码完成后通知到你的业务服务器。
$notifyUrl = 'http://375dec79.ngrok.com/notify.php';
$force = false;
$config = new \Qiniu\Config();
//$config->useHTTPS=true;
$pfop = new PersistentFop($auth, $config);
//需要添加水印的图片UrlSafeBase64
//可以参考http://developer.qiniu.com/code/v6/api/dora-api/av/video-watermark.html
$base64URL = Qiniu\base64_urlSafeEncode('http://devtools.qiniu.com/qiniu.png');
//水印参数
$fops = "avthumb/mp4/s/640x360/vb/1.4m/image/" . $base64URL . "|saveas/"
. \Qiniu\base64_urlSafeEncode($bucket . ":qiniu_wm.mp4");
list($id, $err) = $pfop->execute($bucket, $key, $fops, $pipeline, $notifyUrl, $force);
echo "\n====> pfop avthumb result: \n";
if ($err != null) {
var_dump($err);
} else {
echo "PersistentFop Id: $id\n";
}
//查询转码的进度和状态
list($ret, $err) = $pfop->status($id);
echo "\n====> pfop avthumb status: \n";
if ($err != null) {
var_dump($err);
} else {
var_dump($ret);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@@ -0,0 +1,29 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
use Qiniu\Processing\PersistentFop;
$accessKey = 'Access_Key';
$secretKey = 'Secret_Key';
$auth = new Auth($accessKey, $secretKey);
//要持久化处理的文件所在的空间和文件名。
$bucket = 'Bucket_Name';
//持久化处理使用的队列名称。 https://portal.qiniu.com/mps/pipeline
$pipeline = 'pipeline_name';
//持久化处理完成后通知到你的业务服务器。
$notifyUrl = 'http://375dec79.ngrok.com/notify.php';
$pfop = new PersistentFop($auth, $bucket, $pipeline, $notifyUrl);
$id = "z2.5955c739e3d0041bf80c9baa";
//查询持久化处理的进度和状态
list($ret, $err) = $pfop->status($id);
echo "\n====> pfop avthumb status: \n";
if ($err != null) {
var_dump($err);
} else {
var_dump($ret);
}

View File

@@ -0,0 +1,55 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
use Qiniu\Http\Client;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$argusManager = new \Qiniu\Storage\ArgusManager($auth, $config);
$reqBody = array();
$reqBody['uri'] = "xxxx";
$ops = array();
$ops = array(
array(
'op' => 'pulp',
'params' => array(
'labels' => array(
array(
'label' => "1",
'select' => 1,
'score' => 2,
),
)
)
),
);
$params = array();
$params = array(
'async' => false,
'vframe' => array(
'mode' => 1,
'interval' => 8,
)
);
$req = array();
$req['data'] = $reqBody;
$req['ops'] = $ops;
$req['params'] = $params;
$body = json_encode($req);
$vid = "xxxx";
list($ret, $err) = $argusManager->pulpVideo($body, $vid);
if ($err !== null) {
var_dump($err);
} else {
var_dump($ret);
}

View File

@@ -0,0 +1,11 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Etag;
$localFile = "/Users/jemy/Documents/qiniu.mp4";
list($etag, $err) = Etag::sum($localFile);
if ($err == null) {
echo "Etag: $etag";
} else {
var_dump($err);
}

View File

@@ -0,0 +1,28 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
//每次最多不能超过1000个
$keyMimePairs = array(
'qiniu.mp4' => 'video/x-mp4',
'qiniu.png' => 'image/x-png',
'qiniu.jpg' => 'image/x-jpg'
);
$ops = $bucketManager->buildBatchChangeMime($bucket, $keyMimePairs);
list($ret, $err) = $bucketManager->batch($ops);
if ($err) {
print_r($err);
} else {
print_r($ret);
}

View File

@@ -0,0 +1,34 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
//每次最多不能超过1000个
$keys = array(
'qiniu.mp4',
'qiniu.png',
'qiniu.jpg'
);
$keyTypePairs = array();
//type=0表示普通存储type=1表示低频存储
foreach ($keys as $key) {
$keyTypePairs[$key] = 1;
}
$ops = $bucketManager->buildBatchChangeType($bucket, $keyTypePairs);
list($ret, $err) = $bucketManager->batch($ops);
if ($err) {
print_r($err);
} else {
print_r($ret);
}

View File

@@ -0,0 +1,36 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
//每次最多不能超过1000个
$keys = array(
'qiniu.mp4',
'qiniu.png',
'qiniu.jpg'
);
$keyPairs = array();
foreach ($keys as $key) {
$keyPairs[$key] = $key . "_copy";
}
$srcBucket = $bucket;
$destBucket = $bucket;
$ops = $bucketManager->buildBatchCopy($srcBucket, $keyPairs, $destBucket, true);
list($ret, $err) = $bucketManager->batch($ops);
if ($err) {
print_r($err);
} else {
print_r($ret);
}

View File

@@ -0,0 +1,28 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
//每次最多不能超过1000个
$keys = array(
'qiniu.mp4',
'qiniu.png',
'qiniu.jpg'
);
$ops = $bucketManager->buildBatchDelete($bucket, $keys);
list($ret, $err) = $bucketManager->batch($ops);
if ($err) {
print_r($err);
} else {
print_r($ret);
}

View File

@@ -0,0 +1,34 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
//每次最多不能超过1000个
$keys = array(
'qiniu.mp4',
'qiniu.png',
'qiniu.jpg'
);
$keyDayPairs = array();
//day=0表示永久存储
foreach ($keys as $key) {
$keyDayPairs[$key] = 0;
}
$ops = $bucketManager->buildBatchDeleteAfterDays($bucket, $keyDayPairs);
list($ret, $err) = $bucketManager->batch($ops);
if ($err) {
print_r($err);
} else {
print_r($ret);
}

View File

@@ -0,0 +1,36 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
//每次最多不能超过1000个
$keys = array(
'qiniu.mp4',
'qiniu.png',
'qiniu.jpg'
);
$keyPairs = array();
foreach ($keys as $key) {
$keyPairs[$key . "_copy"] = $key . "_move";
}
$srcBucket = $bucket;
$destBucket = $bucket;
$ops = $bucketManager->buildBatchMove($srcBucket, $keyPairs, $destBucket, true);
list($ret, $err) = $bucketManager->batch($ops);
if ($err) {
print_r($err);
} else {
print_r($ret);
}

View File

@@ -0,0 +1,28 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
//每次最多不能超过1000个
$keys = array(
'qiniu.mp4',
'qiniu.png',
'qiniu.jpg'
);
$ops = $bucketManager->buildBatchStat($bucket, $keys);
list($ret, $err) = $bucketManager->batch($ops);
if ($err) {
print_r($err);
} else {
print_r($ret);
}

View File

@@ -0,0 +1,19 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
list($domains, $err) = $bucketManager->domains($bucket);
if ($err) {
print_r($err);
} else {
print_r($domains);
}

View File

@@ -0,0 +1,19 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
list($buckets, $err) = $bucketManager->buckets(true);
if ($err) {
print_r($err);
} else {
print_r($buckets);
}

View File

@@ -0,0 +1,20 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$key = 'qiniu.mp4';
$newMime = 'video/x-mp4';
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
$err = $bucketManager->changeMime($bucket, $key, $newMime);
if ($err) {
print_r($err);
}

View File

@@ -0,0 +1,20 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$key = "qiniu.jpg";
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
$status = 1;//0表示启用1表示禁用
$err = $bucketManager->changeStatus($bucket, $key, $status);
if ($err) {
print_r($err);
}

View File

@@ -0,0 +1,20 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$key = "qiniu.mp4";
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
$fileType = 1;//0 表示普通存储1表示低频存储
$err = $bucketManager->changeType($bucket, $key, $fileType);
if ($err) {
print_r($err);
}

View File

@@ -0,0 +1,22 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$key = "qiniu.mp4";
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
$srcBucket = $bucket;
$destBucket = $bucket;
$srcKey = $key;
$destKey = $key . "_copy";
$err = $bucketManager->copy($srcBucket, $srcKey, $destBucket, $destKey, true);
if ($err) {
print_r($err);
}

View File

@@ -0,0 +1,17 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$key = "qiniu.mp4_copy";
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
$err = $bucketManager->delete($bucket, $key);
if ($err) {
print_r($err);
}

View File

@@ -0,0 +1,20 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$key = 'qiniu.mp4';
$days = 10;
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
$err = $bucketManager->deleteAfterDays($bucket, $key, $days);
if ($err) {
print_r($err);
}

View File

@@ -0,0 +1,17 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
// 构建Auth对象
$auth = new Auth($accessKey, $secretKey);
// 私有空间中的外链 http://<domain>/<file_key>
$baseUrl = 'http://if-pri.qiniudn.com/qiniu.png?imageView2/1/h/500';
// 对链接进行签名
$signedUrl = $auth->privateDownloadUrl($baseUrl);
echo $signedUrl;

View File

@@ -0,0 +1,34 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
use Qiniu\Storage\BucketManager;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
$bucketManager = new BucketManager($auth);
$url = 'http://devtools.qiniu.com/qiniu.png';
$key = time() . '.png';
// 指定抓取的文件保存名称
list($ret, $err) = $bucketManager->fetch($url, $bucket, $key);
echo "=====> fetch $url to bucket: $bucket key: $key\n";
if ($err !== null) {
var_dump($err);
} else {
print_r($ret);
}
// 不指定key时以文件内容的hash作为文件名
$key = null;
list($ret, $err) = $bucketManager->fetch($url, $bucket, $key);
echo "=====> fetch $url to bucket: $bucket key: $(etag)\n";
if ($err !== null) {
var_dump($err);
} else {
print_r($ret);
}

View File

@@ -0,0 +1,22 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$key = "qiniu.mp4";
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
$srcBucket = $bucket;
$destBucket = $bucket;
$srcKey = $key . "_copy";
$destKey = $key . "_move";
$err = $bucketManager->move($srcBucket, $srcKey, $destBucket, $destKey, true);
if ($err) {
print_r($err);
}

View File

@@ -0,0 +1,17 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$key = "qiniu.mp4";
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
$err = $bucketManager->prefetch($bucket, $key);
if ($err) {
print_r($err);
}

View File

@@ -0,0 +1,19 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$key = "qiniu.mp4";
$auth = new Auth($accessKey, $secretKey);
$config = new \Qiniu\Config();
$bucketManager = new \Qiniu\Storage\BucketManager($auth, $config);
list($fileInfo, $err) = $bucketManager->stat($bucket, $key);
if ($err) {
print_r($err);
} else {
print_r($fileInfo);
}

View File

@@ -0,0 +1,46 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
use Qiniu\Storage\BucketManager;
// http://developer.qiniu.com/docs/v6/api/reference/rs/list.html#list-description
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
$bucketManager = new BucketManager($auth);
// 要列取文件的公共前缀
$prefix = '';
// 上次列举返回的位置标记,作为本次列举的起点信息。
$marker = '';
// 本次列举的条目数
$limit = 200;
$delimiter = '/';
// 列举文件
do {
list($ret, $err) = $bucketManager->listFiles($bucket, $prefix, $marker, $limit, $delimiter);
if ($err !== null) {
echo "\n====> list file err: \n";
var_dump($err);
} else {
$marker = null;
if (array_key_exists('marker', $ret)) {
$marker = $ret['marker'];
}
echo "Marker: $marker\n";
echo "\nList Items====>\n";
//var_dump($ret['items']);
print('items count:' . count($ret['items']) . "\n");
if (array_key_exists('commonPrefixes', $ret)) {
print_r($ret['commonPrefixes']);
}
}
} while (!empty($marker));

View File

@@ -0,0 +1,38 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
use Qiniu\Storage\BucketManager;
// http://developer.qiniu.com/docs/v6/api/reference/rs/list.html#list-description
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
$bucketManager = new BucketManager($auth);
// 要列取文件的公共前缀
$prefix = '';
// 上次列举返回的位置标记,作为本次列举的起点信息。
$marker = '';
// 本次列举的条目数
$limit = 100;
$delimiter = '/';
// 列举文件
list($ret, $err) = $bucketManager->listFiles($bucket, $prefix, $marker, $limit, $delimiter);
if ($err !== null) {
echo "\n====> list file err: \n";
var_dump($err);
} else {
if (array_key_exists('marker', $ret)) {
echo "Marker:" . $ret["marker"] . "\n";
}
echo "\nList Iterms====>\n";
//var_dump($ret['items']);
}

View File

@@ -0,0 +1,28 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
use Qiniu\Processing\PersistentFop;
// 后台来获取AK, SK
$accessKey = 'Access_Key';
$secretKey = 'Secret_Key';
//生成EncodedEntryURI的值
$entry = '<bucket>:<Key>';//<Key>为生成缩略图的文件名
//生成的值
$encodedEntryURI = \Qiniu\base64_urlSafeEncode($entry);
//使用SecretKey对新的下载URL进行HMAC1-SHA1签名
$newurl = "78re52.com1.z0.glb.clouddn.com/resource/Ship.jpg?imageView2/2/w/200/h/200|saveas/" . $encodedEntryURI;
$sign = hash_hmac("sha1", $newurl, $secretKey, true);
//对签名进行URL安全的Base64编码
$encodedSign = \Qiniu\base64_urlSafeEncode($sign);
//最终得到的完整下载URL
$finalURL = "http://" . $newurl . "/sign/" . $accessKey . ":" . $encodedSign;
$callbackBody = file_get_contents("$finalURL");
echo $callbackBody;

View File

@@ -0,0 +1,40 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
// use Qiniu\Config;
// use Qiniu\Zone;
// 指定zone上传
// $zone = Zone::zoneZ0(); //华东QVM内网上传指定host
// $config = new Config($zone);
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
// 上传文件到七牛后, 七牛将文件名和文件大小回调给业务服务器.
// 可参考文档: http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html
$policy = array(
'callbackUrl' => 'http://your.domain.com/upload_verify_callback.php',
'callbackBody' => 'filename=$(fname)&filesize=$(fsize)'
);
$uptoken = $auth->uploadToken($bucket, null, 3600, $policy);
//上传文件的本地路径
$filePath = './php-logo.png';
//指定 config
// $uploadMgr = new UploadManager($config);
$uploadMgr = new UploadManager();
list($ret, $err) = $uploadMgr->putFile($uptoken, null, $filePath);
echo "\n====> putFile result: \n";
if ($err !== null) {
var_dump($err);
} else {
var_dump($ret);
}

View File

@@ -0,0 +1,38 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
// 在七牛保存的文件名
$key = 'php-logo.png';
$uploadMgr = new UploadManager();
$pfop = "imageMogr2/rotate/90|saveas/" . \Qiniu\base64_urlSafeEncode($bucket . ":php-logo-rotate.png");
//转码完成后通知到你的业务服务器。公网可以访问并相应200 OK
$notifyUrl = 'http://notify.fake.com';
//独立的转码队列https://portal.qiniu.com/mps/pipeline
$pipeline = 'sdktest';
$policy = array(
'persistentOps' => $pfop,
'persistentNotifyUrl' => $notifyUrl,
'persistentPipeline' => $pipeline
);
$token = $auth->uploadToken($bucket, null, 3600, $policy);
list($ret, $err) = $uploadMgr->putFile($token, null, $key);
echo "\n====> putFile result: \n";
if ($err !== null) {
var_dump($err);
} else {
var_dump($ret);
}

View File

@@ -0,0 +1,18 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
$accessKey = 'Access_Key';
$secretKey = 'Secret_Key';
$auth = new Auth($accessKey, $secretKey);
// 空间名 http://developer.qiniu.com/docs/v6/api/overview/concepts.html#bucket
$bucket = 'Bucket_Name';
// 生成上传Token
$token = $auth->uploadToken($bucket);
// 构建 UploadManager 对象
$uploadMgr = new UploadManager();

View File

@@ -0,0 +1,85 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$pipeline = 'sdktest';
$auth = new Auth($accessKey, $secretKey);
$token = $auth->uploadToken($bucket);
$uploadMgr = new UploadManager();
//----------------------------------------upload demo1 ----------------------------------------
// 上传字符串到七牛
list($ret, $err) = $uploadMgr->put($token, null, 'content string');
echo "\n====> put result: \n";
if ($err !== null) {
var_dump($err);
} else {
var_dump($ret);
}
//----------------------------------------upload demo2 ----------------------------------------
// 上传文件到七牛
$filePath = './php-logo.png';
$key = 'php-logo.png';
list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath);
echo "\n====> putFile result: \n";
if ($err !== null) {
var_dump($err);
} else {
var_dump($ret);
}
//----------------------------------------upload demo3 ----------------------------------------
// 上传文件到七牛后, 七牛将文件名和文件大小回调给业务服务器.
// 可参考文档: http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html
$policy = array(
'callbackUrl' => 'http://172.30.251.210/upload_verify_callback.php',
'callbackBody' => 'filename=$(fname)&filesize=$(fsize)'
// 'callbackBodyType' => 'application/json',
// 'callbackBody' => '{"filename":$(fname), "filesize": $(fsize)}' //设置application/json格式回调
);
$token = $auth->uploadToken($bucket, null, 3600, $policy);
list($ret, $err) = $uploadMgr->putFile($token, null, $key);
echo "\n====> putFile result: \n";
if ($err !== null) {
var_dump($err);
} else {
var_dump($ret);
}
//----------------------------------------upload demo4 ----------------------------------------
//上传视频上传完成后进行m3u8的转码 并给视频打水印
$wmImg = Qiniu\base64_urlSafeEncode('http://devtools.qiniudn.com/qiniu.png');
$pfop = "avthumb/m3u8/wmImage/$wmImg";
//转码完成后回调到业务服务器。公网可以访问并相应200 OK
$notifyUrl = 'http://notify.fake.com';
//独立的转码队列https://portal.qiniu.com/mps/pipeline
$policy = array(
'persistentOps' => $pfop,
'persistentNotifyUrl' => $notifyUrl,
'persistentPipeline' => $pipeline
);
$token = $auth->uploadToken($bucket, null, 3600, $policy);
print($token);
list($ret, $err) = $uploadMgr->putFile($token, null, $key);
echo "\n====> putFile result: \n";
if ($err !== null) {
var_dump($err);
} else {
var_dump($ret);
}

View File

@@ -0,0 +1,37 @@
<?php
require_once __DIR__ . '/../autoload.php';
// 引入鉴权类
use Qiniu\Auth;
// 引入上传类
use Qiniu\Storage\UploadManager;
// 需要填写你的 Access Key 和 Secret Key
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
// 构建鉴权对象
$auth = new Auth($accessKey, $secretKey);
// 生成上传 Token
$token = $auth->uploadToken($bucket);
// 要上传文件的本地路径
$filePath = './php-logo.png';
// 上传到七牛后保存的文件名
$key = 'my-php-logo.png';
// 初始化 UploadManager 对象并进行文件的上传。
$uploadMgr = new UploadManager();
// 调用 UploadManager 的 putFile 方法进行文件的上传。
list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath);
echo "\n====> putFile result: \n";
if ($err !== null) {
var_dump($err);
} else {
var_dump($ret);
}

View File

@@ -0,0 +1,68 @@
<?php
require_once __DIR__ . '/../autoload.php';
use \Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
// 初始化Auth状态
$auth = new Auth($accessKey, $secretKey);
// 简单上传凭证
$expires = 3600;
$policy = null;
$upToken = $auth->uploadToken($bucket, null, $expires, $policy, true);
print($upToken . "\n");
// 自定义凭证有效期示例2小时
$expires = 7200;
$upToken = $auth->uploadToken($bucket, null, $expires, $policy, true);
print($upToken . "\n");
// 覆盖上传凭证
$expires = 3600;
$keyToOverwrite = 'qiniu.mp4';
$upToken = $auth->uploadToken($bucket, $keyToOverwrite, $expires, $policy, true);
print($upToken . "\n");
//自定义上传回复非callback模式凭证
$returnBody = '{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}';
$policy = array(
'returnBody' => $returnBody
);
$upToken = $auth->uploadToken($bucket, null, $expires, $policy, true);
print($upToken . "\n");
//带回调业务服务器的凭证application/json
$policy = array(
'callbackUrl' => 'http://api.example.com/qiniu/upload/callback',
'callbackBody' => '{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}',
'callbackBodyType' => 'application/json'
);
$upToken = $auth->uploadToken($bucket, null, $expires, $policy, true);
print($upToken . "\n");
//带回调业务服务器的凭证application/x-www-form-urlencoded
$policy = array(
'callbackUrl' => 'http://api.example.com/qiniu/upload/callback',
'callbackBody' => 'key=$(key)&hash=$(etag)&bucket=$(bucket)&fsize=$(fsize)&name=$(x:name)'
);
$upToken = $auth->uploadToken($bucket, null, $expires, $policy, true);
print($upToken . "\n");
//带数据处理的凭证
$saveMp4Entry = \Qiniu\base64_urlSafeEncode($bucket . ":avthumb_test_target.mp4");
$saveJpgEntry = \Qiniu\base64_urlSafeEncode($bucket . ":vframe_test_target.jpg");
$avthumbMp4Fop = "avthumb/mp4|saveas/" . $saveMp4Entry;
$vframeJpgFop = "vframe/jpg/offset/1|saveas/" . $saveJpgEntry;
$policy = array(
'persistentOps' => $avthumbMp4Fop . ";" . $vframeJpgFop,
'persistentPipeline' => "video-pipe",
'persistentNotifyUrl' => "http://api.example.com/qiniu/pfop/notify",
);
$upToken = $auth->uploadToken($bucket, null, $expires, $policy, true);
print($upToken . "\n");

View File

@@ -0,0 +1,32 @@
<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$bucket = getenv('QINIU_TEST_BUCKET');
$auth = new Auth($accessKey, $secretKey);
//获取回调的body信息
$callbackBody = file_get_contents('php://input');
//回调的contentType
$contentType = 'application/x-www-form-urlencoded';
//回调的签名信息,可以验证该回调是否来自七牛
$authorization = $_SERVER['HTTP_AUTHORIZATION'];
//七牛回调的url具体可以参考http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html
$url = 'http://172.30.251.210/upload_verify_callback.php';
$isQiniuCallback = $auth->verifyCallback($contentType, $authorization, $url, $callbackBody);
if ($isQiniuCallback) {
$resp = array('ret' => 'success');
} else {
$resp = array('ret' => 'failed');
}
echo json_encode($resp);

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="./tests/bootstrap.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="true"
>
<testsuites>
<testsuite name="Qiniu SDK Tests">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>

View File

@@ -0,0 +1,187 @@
<?php
namespace Qiniu;
use Qiniu\Zone;
final class Auth
{
private $accessKey;
private $secretKey;
public function __construct($accessKey, $secretKey)
{
$this->accessKey = $accessKey;
$this->secretKey = $secretKey;
}
public function getAccessKey()
{
return $this->accessKey;
}
public function sign($data)
{
$hmac = hash_hmac('sha1', $data, $this->secretKey, true);
return $this->accessKey . ':' . \Qiniu\base64_urlSafeEncode($hmac);
}
public function signWithData($data)
{
$encodedData = \Qiniu\base64_urlSafeEncode($data);
return $this->sign($encodedData) . ':' . $encodedData;
}
public function signRequest($urlString, $body, $contentType = null)
{
$url = parse_url($urlString);
$data = '';
if (array_key_exists('path', $url)) {
$data = $url['path'];
}
if (array_key_exists('query', $url)) {
$data .= '?' . $url['query'];
}
$data .= "\n";
if ($body !== null && $contentType === 'application/x-www-form-urlencoded') {
$data .= $body;
}
return $this->sign($data);
}
public function verifyCallback($contentType, $originAuthorization, $url, $body)
{
$authorization = 'QBox ' . $this->signRequest($url, $body, $contentType);
return $originAuthorization === $authorization;
}
public function privateDownloadUrl($baseUrl, $expires = 3600)
{
$deadline = time() + $expires;
$pos = strpos($baseUrl, '?');
if ($pos !== false) {
$baseUrl .= '&e=';
} else {
$baseUrl .= '?e=';
}
$baseUrl .= $deadline;
$token = $this->sign($baseUrl);
return "$baseUrl&token=$token";
}
public function uploadToken($bucket, $key = null, $expires = 3600, $policy = null, $strictPolicy = true)
{
$deadline = time() + $expires;
$scope = $bucket;
if ($key !== null) {
$scope .= ':' . $key;
}
$args = self::copyPolicy($args, $policy, $strictPolicy);
$args['scope'] = $scope;
$args['deadline'] = $deadline;
$b = json_encode($args);
return $this->signWithData($b);
}
/**
*上传策略,参数规格详见
*http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html
*/
private static $policyFields = array(
'callbackUrl',
'callbackBody',
'callbackHost',
'callbackBodyType',
'callbackFetchKey',
'returnUrl',
'returnBody',
'endUser',
'saveKey',
'insertOnly',
'detectMime',
'mimeLimit',
'fsizeMin',
'fsizeLimit',
'persistentOps',
'persistentNotifyUrl',
'persistentPipeline',
'deleteAfterDays',
'fileType',
'isPrefixalScope',
);
private static function copyPolicy(&$policy, $originPolicy, $strictPolicy)
{
if ($originPolicy === null) {
return array();
}
foreach ($originPolicy as $key => $value) {
if (!$strictPolicy || in_array((string)$key, self::$policyFields, true)) {
$policy[$key] = $value;
}
}
return $policy;
}
public function authorization($url, $body = null, $contentType = null)
{
$authorization = 'QBox ' . $this->signRequest($url, $body, $contentType);
return array('Authorization' => $authorization);
}
public function authorizationV2($url, $method, $body = null, $contentType = null)
{
$urlItems = parse_url($url);
$host = $urlItems['host'];
if (isset($urlItems['port'])) {
$port = $urlItems['port'];
} else {
$port = '';
}
$path = $urlItems['path'];
if (isset($urlItems['query'])) {
$query = $urlItems['query'];
} else {
$query = '';
}
//write request uri
$toSignStr = $method . ' ' . $path;
if (!empty($query)) {
$toSignStr .= '?' . $query;
}
//write host and port
$toSignStr .= "\nHost: " . $host;
if (!empty($port)) {
$toSignStr .= ":" . $port;
}
//write content type
if (!empty($contentType)) {
$toSignStr .= "\nContent-Type: " . $contentType;
}
$toSignStr .= "\n\n";
//write body
if (!empty($body)) {
$toSignStr .= $body;
}
$sign = $this->sign($toSignStr);
$auth = 'Qiniu ' . $sign;
return array('Authorization' => $auth);
}
}

View File

@@ -0,0 +1,191 @@
<?php
namespace Qiniu\Cdn;
use Qiniu\Auth;
use Qiniu\Http\Error;
use Qiniu\Http\Client;
final class CdnManager
{
private $auth;
private $server;
public function __construct(Auth $auth)
{
$this->auth = $auth;
$this->server = 'http://fusion.qiniuapi.com';
}
/**
* @param array $urls 待刷新的文件链接数组
* @return array
*/
public function refreshUrls(array $urls)
{
return $this->refreshUrlsAndDirs($urls, array());
}
/**
* @param array $dirs 待刷新的文件链接数组
* @return array
* 目前客户默认没有目录刷新权限刷新会有400038报错参考https://developer.qiniu.com/fusion/api/1229/cache-refresh
* 需要刷新目录请工单联系技术支持 https://support.qiniu.com/tickets/category
*/
public function refreshDirs(array $dirs)
{
return $this->refreshUrlsAndDirs(array(), $dirs);
}
/**
* @param array $urls 待刷新的文件链接数组
* @param array $dirs 待刷新的目录链接数组
*
* @return array 刷新的请求回复和错误,参考 examples/cdn_manager.php 代码
* @link http://developer.qiniu.com/article/fusion/api/refresh.html
*
* 目前客户默认没有目录刷新权限刷新会有400038报错参考https://developer.qiniu.com/fusion/api/1229/cache-refresh
* 需要刷新目录请工单联系技术支持 https://support.qiniu.com/tickets/category
*/
public function refreshUrlsAndDirs(array $urls, array $dirs)
{
$req = array();
if (!empty($urls)) {
$req['urls'] = $urls;
}
if (!empty($dirs)) {
$req['dirs'] = $dirs;
}
$url = $this->server . '/v2/tune/refresh';
$body = json_encode($req);
return $this->post($url, $body);
}
/**
* @param array $urls 待预取的文件链接数组
*
* @return array 预取的请求回复和错误,参考 examples/cdn_manager.php 代码
*
* @link http://developer.qiniu.com/article/fusion/api/refresh.html
*/
public function prefetchUrls(array $urls)
{
$req = array(
'urls' => $urls,
);
$url = $this->server . '/v2/tune/prefetch';
$body = json_encode($req);
return $this->post($url, $body);
}
/**
* @param array $domains 待获取带宽数据的域名数组
* @param string $startDate 开始的日期,格式类似 2017-01-01
* @param string $endDate 结束的日期,格式类似 2017-01-01
* @param string $granularity 获取数据的时间间隔,可以是 5min, hour 或者 day
*
* @return array 带宽数据和错误信息,参考 examples/cdn_manager.php 代码
*
* @link http://developer.qiniu.com/article/fusion/api/traffic-bandwidth.html
*/
public function getBandwidthData(array $domains, $startDate, $endDate, $granularity)
{
$req = array();
$req['domains'] = implode(';', $domains);
$req['startDate'] = $startDate;
$req['endDate'] = $endDate;
$req['granularity'] = $granularity;
$url = $this->server . '/v2/tune/bandwidth';
$body = json_encode($req);
return $this->post($url, $body);
}
/**
* @param array $domains 待获取流量数据的域名数组
* @param string $startDate 开始的日期,格式类似 2017-01-01
* @param string $endDate 结束的日期,格式类似 2017-01-01
* @param string $granularity 获取数据的时间间隔,可以是 5min, hour 或者 day
*
* @return array 流量数据和错误信息,参考 examples/cdn_manager.php 代码
*
* @link http://developer.qiniu.com/article/fusion/api/traffic-bandwidth.html
*/
public function getFluxData(array $domains, $startDate, $endDate, $granularity)
{
$req = array();
$req['domains'] = implode(';', $domains);
$req['startDate'] = $startDate;
$req['endDate'] = $endDate;
$req['granularity'] = $granularity;
$url = $this->server . '/v2/tune/flux';
$body = json_encode($req);
return $this->post($url, $body);
}
/**
* @param array $domains 待获取日志下载链接的域名数组
* @param string $logDate 获取指定日期的日志下载链接,格式类似 2017-01-01
*
* @return array 日志下载链接数据和错误信息,参考 examples/cdn_manager.php 代码
*
* @link http://developer.qiniu.com/article/fusion/api/log.html
*/
public function getCdnLogList(array $domains, $logDate)
{
$req = array();
$req['domains'] = implode(';', $domains);
$req['day'] = $logDate;
$url = $this->server . '/v2/tune/log/list';
$body = json_encode($req);
return $this->post($url, $body);
}
private function post($url, $body)
{
$headers = $this->auth->authorization($url, $body, 'application/json');
$headers['Content-Type'] = 'application/json';
$ret = Client::post($url, $body, $headers);
if (!$ret->ok()) {
return array(null, new Error($url, $ret));
}
$r = ($ret->body === null) ? array() : $ret->json();
return array($r, null);
}
/**
* 构建时间戳防盗链鉴权的访问外链
*
* @param string $rawUrl 需要签名的资源url
* @param string $encryptKey 时间戳防盗链密钥
* @param string $durationInSeconds 链接的有效期(以秒为单位)
*
* @return string 带鉴权信息的资源外链,参考 examples/cdn_timestamp_antileech.php 代码
*/
public static function createTimestampAntiLeechUrl($rawUrl, $encryptKey, $durationInSeconds)
{
$parsedUrl = parse_url($rawUrl);
$deadline = time() + $durationInSeconds;
$expireHex = dechex($deadline);
$path = isset($parsedUrl['path']) ? $parsedUrl['path'] : '';
$path = implode('/', array_map('rawurlencode', explode('/', $path)));
$strToSign = $encryptKey . $path . $expireHex;
$signStr = md5($strToSign);
if (isset($parsedUrl['query'])) {
$signedUrl = $rawUrl . '&sign=' . $signStr . '&t=' . $expireHex;
} else {
$signedUrl = $rawUrl . '?sign=' . $signStr . '&t=' . $expireHex;
}
return $signedUrl;
}
}

View File

@@ -0,0 +1,137 @@
<?php
namespace Qiniu;
final class Config
{
const SDK_VER = '7.2.7';
const BLOCK_SIZE = 4194304; //4*1024*1024 分块上传块大小,该参数为接口规格,不能修改
const RSF_HOST = 'rsf.qiniu.com';
const API_HOST = 'api.qiniu.com';
const RS_HOST = 'rs.qiniu.com'; //RS Host
const UC_HOST = 'https://api.qiniu.com'; //UC Host
const RTCAPI_HOST = 'http://rtc.qiniuapi.com';
const ARGUS_HOST = 'argus.atlab.ai';
const RTCAPI_VERSION = 'v3';
// Zone 空间对应的机房
public $zone;
//BOOL 是否使用https域名
public $useHTTPS;
//BOOL 是否使用CDN加速上传域名
public $useCdnDomains;
// Zone Cache
private $zoneCache;
// 构造函数
public function __construct(Zone $z = null)
{
$this->zone = $z;
$this->useHTTPS = false;
$this->useCdnDomains = false;
$this->zoneCache = array();
}
public function getUpHost($accessKey, $bucket)
{
$zone = $this->getZone($accessKey, $bucket);
if ($this->useHTTPS === true) {
$scheme = "https://";
} else {
$scheme = "http://";
}
$host = $zone->srcUpHosts[0];
if ($this->useCdnDomains === true) {
$host = $zone->cdnUpHosts[0];
}
return $scheme . $host;
}
public function getUpBackupHost($accessKey, $bucket)
{
$zone = $this->getZone($accessKey, $bucket);
if ($this->useHTTPS === true) {
$scheme = "https://";
} else {
$scheme = "http://";
}
$host = $zone->cdnUpHosts[0];
if ($this->useCdnDomains === true) {
$host = $zone->srcUpHosts[0];
}
return $scheme . $host;
}
public function getRsHost($accessKey, $bucket)
{
$zone = $this->getZone($accessKey, $bucket);
if ($this->useHTTPS === true) {
$scheme = "https://";
} else {
$scheme = "http://";
}
return $scheme . $zone->rsHost;
}
public function getRsfHost($accessKey, $bucket)
{
$zone = $this->getZone($accessKey, $bucket);
if ($this->useHTTPS === true) {
$scheme = "https://";
} else {
$scheme = "http://";
}
return $scheme . $zone->rsfHost;
}
public function getIovipHost($accessKey, $bucket)
{
$zone = $this->getZone($accessKey, $bucket);
if ($this->useHTTPS === true) {
$scheme = "https://";
} else {
$scheme = "http://";
}
return $scheme . $zone->iovipHost;
}
public function getApiHost($accessKey, $bucket)
{
$zone = $this->getZone($accessKey, $bucket);
if ($this->useHTTPS === true) {
$scheme = "https://";
} else {
$scheme = "http://";
}
return $scheme . $zone->apiHost;
}
private function getZone($accessKey, $bucket)
{
$cacheId = "$accessKey:$bucket";
if (isset($this->zoneCache[$cacheId])) {
$zone = $this->zoneCache[$cacheId];
} elseif (isset($this->zone)) {
$zone = $this->zone;
$this->zoneCache[$cacheId] = $zone;
} else {
$zone = Zone::queryZone($accessKey, $bucket);
$this->zoneCache[$cacheId] = $zone;
}
return $zone;
}
}

View File

@@ -0,0 +1,76 @@
<?php
namespace Qiniu;
use Qiniu\Config;
final class Etag
{
private static function packArray($v, $a)
{
return call_user_func_array('pack', array_merge(array($v), (array)$a));
}
private static function blockCount($fsize)
{
return intval(($fsize + (Config::BLOCK_SIZE - 1)) / Config::BLOCK_SIZE);
}
private static function calcSha1($data)
{
$sha1Str = sha1($data, true);
$err = error_get_last();
if ($err !== null) {
return array(null, $err);
}
$byteArray = unpack('C*', $sha1Str);
return array($byteArray, null);
}
public static function sum($filename)
{
$fhandler = fopen($filename, 'r');
$err = error_get_last();
if ($err !== null) {
return array(null, $err);
}
$fstat = fstat($fhandler);
$fsize = $fstat['size'];
if ((int)$fsize === 0) {
fclose($fhandler);
return array('Fto5o-5ea0sNMlW_75VgGJCv2AcJ', null);
}
$blockCnt = self::blockCount($fsize);
$sha1Buf = array();
if ($blockCnt <= 1) {
array_push($sha1Buf, 0x16);
$fdata = fread($fhandler, Config::BLOCK_SIZE);
if ($err !== null) {
fclose($fhandler);
return array(null, $err);
}
list($sha1Code,) = self::calcSha1($fdata);
$sha1Buf = array_merge($sha1Buf, $sha1Code);
} else {
array_push($sha1Buf, 0x96);
$sha1BlockBuf = array();
for ($i = 0; $i < $blockCnt; $i++) {
$fdata = fread($fhandler, Config::BLOCK_SIZE);
list($sha1Code, $err) = self::calcSha1($fdata);
if ($err !== null) {
fclose($fhandler);
return array(null, $err);
}
$sha1BlockBuf = array_merge($sha1BlockBuf, $sha1Code);
}
$tmpData = self::packArray('C*', $sha1BlockBuf);
list($sha1Final,) = self::calcSha1($tmpData);
$sha1Buf = array_merge($sha1Buf, $sha1Final);
}
$etag = \Qiniu\base64_urlSafeEncode(self::packArray('C*', $sha1Buf));
return array($etag, null);
}
}

View File

@@ -0,0 +1,156 @@
<?php
namespace Qiniu\Http;
use Qiniu\Config;
use Qiniu\Http\Request;
use Qiniu\Http\Response;
final class Client
{
public static function get($url, array $headers = array())
{
$request = new Request('GET', $url, $headers);
return self::sendRequest($request);
}
public static function delete($url, array $headers = array())
{
$request = new Request('DELETE', $url, $headers);
return self::sendRequest($request);
}
public static function post($url, $body, array $headers = array())
{
$request = new Request('POST', $url, $headers, $body);
return self::sendRequest($request);
}
public static function multipartPost(
$url,
$fields,
$name,
$fileName,
$fileBody,
$mimeType = null,
array $headers = array()
) {
$data = array();
$mimeBoundary = md5(microtime());
foreach ($fields as $key => $val) {
array_push($data, '--' . $mimeBoundary);
array_push($data, "Content-Disposition: form-data; name=\"$key\"");
array_push($data, '');
array_push($data, $val);
}
array_push($data, '--' . $mimeBoundary);
$finalMimeType = empty($mimeType) ? 'application/octet-stream' : $mimeType;
$finalFileName = self::escapeQuotes($fileName);
array_push($data, "Content-Disposition: form-data; name=\"$name\"; filename=\"$finalFileName\"");
array_push($data, "Content-Type: $finalMimeType");
array_push($data, '');
array_push($data, $fileBody);
array_push($data, '--' . $mimeBoundary . '--');
array_push($data, '');
$body = implode("\r\n", $data);
$contentType = 'multipart/form-data; boundary=' . $mimeBoundary;
$headers['Content-Type'] = $contentType;
$request = new Request('POST', $url, $headers, $body);
return self::sendRequest($request);
}
private static function userAgent()
{
$sdkInfo = "QiniuPHP/" . Config::SDK_VER;
$systemInfo = php_uname("s");
$machineInfo = php_uname("m");
$envInfo = "($systemInfo/$machineInfo)";
$phpVer = phpversion();
$ua = "$sdkInfo $envInfo PHP/$phpVer";
return $ua;
}
public static function sendRequest($request)
{
$t1 = microtime(true);
$ch = curl_init();
$options = array(
CURLOPT_USERAGENT => self::userAgent(),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_HEADER => true,
CURLOPT_NOBODY => false,
CURLOPT_CUSTOMREQUEST => $request->method,
CURLOPT_URL => $request->url,
);
// Handle open_basedir & safe mode
if (!ini_get('safe_mode') && !ini_get('open_basedir')) {
$options[CURLOPT_FOLLOWLOCATION] = true;
}
if (!empty($request->headers)) {
$headers = array();
foreach ($request->headers as $key => $val) {
array_push($headers, "$key: $val");
}
$options[CURLOPT_HTTPHEADER] = $headers;
}
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
if (!empty($request->body)) {
$options[CURLOPT_POSTFIELDS] = $request->body;
}
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
$t2 = microtime(true);
$duration = round($t2 - $t1, 3);
$ret = curl_errno($ch);
if ($ret !== 0) {
$r = new Response(-1, $duration, array(), null, curl_error($ch));
curl_close($ch);
return $r;
}
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = self::parseHeaders(substr($result, 0, $header_size));
$body = substr($result, $header_size);
curl_close($ch);
return new Response($code, $duration, $headers, $body, null);
}
private static function parseHeaders($raw)
{
$headers = array();
$headerLines = explode("\r\n", $raw);
foreach ($headerLines as $line) {
$headerLine = trim($line);
$kv = explode(':', $headerLine);
if (count($kv) > 1) {
$kv[0] =self::ucwordsHyphen($kv[0]);
$headers[$kv[0]] = trim($kv[1]);
}
}
return $headers;
}
private static function escapeQuotes($str)
{
$find = array("\\", "\"");
$replace = array("\\\\", "\\\"");
return str_replace($find, $replace, $str);
}
private static function ucwordsHyphen($str)
{
return str_replace('- ', '-', ucwords(str_replace('-', '- ', $str)));
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace Qiniu\Http;
/**
* 七牛业务请求逻辑错误封装类主要用来解析API请求返回如下的内容
* <pre>
* {"error" : "detailed error message"}
* </pre>
*/
final class Error
{
private $url;
private $response;
public function __construct($url, $response)
{
$this->url = $url;
$this->response = $response;
}
public function code()
{
return $this->response->statusCode;
}
public function getResponse()
{
return $this->response;
}
public function message()
{
return $this->response->error;
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Qiniu\Http;
final class Request
{
public $url;
public $headers;
public $body;
public $method;
public function __construct($method, $url, array $headers = array(), $body = null)
{
$this->method = strtoupper($method);
$this->url = $url;
$this->headers = $headers;
$this->body = $body;
}
}

View File

@@ -0,0 +1,176 @@
<?php
namespace Qiniu\Http;
/**
* HTTP response Object
*/
final class Response
{
public $statusCode;
public $headers;
public $body;
public $error;
private $jsonData;
public $duration;
/** @var array Mapping of status codes to reason phrases */
private static $statusTexts = array(
100 => 'Continue',
101 => 'Switching Protocols',
102 => 'Processing',
200 => 'OK',
201 => 'Created',
202 => 'Accepted',
203 => 'Non-Authoritative Information',
204 => 'No Content',
205 => 'Reset Content',
206 => 'Partial Content',
207 => 'Multi-Status',
208 => 'Already Reported',
226 => 'IM Used',
300 => 'Multiple Choices',
301 => 'Moved Permanently',
302 => 'Found',
303 => 'See Other',
304 => 'Not Modified',
305 => 'Use Proxy',
307 => 'Temporary Redirect',
308 => 'Permanent Redirect',
400 => 'Bad Request',
401 => 'Unauthorized',
402 => 'Payment Required',
403 => 'Forbidden',
404 => 'Not Found',
405 => 'Method Not Allowed',
406 => 'Not Acceptable',
407 => 'Proxy Authentication Required',
408 => 'Request Timeout',
409 => 'Conflict',
410 => 'Gone',
411 => 'Length Required',
412 => 'Precondition Failed',
413 => 'Request Entity Too Large',
414 => 'Request-URI Too Long',
415 => 'Unsupported Media Type',
416 => 'Requested Range Not Satisfiable',
417 => 'Expectation Failed',
422 => 'Unprocessable Entity',
423 => 'Locked',
424 => 'Failed Dependency',
425 => 'Reserved for WebDAV advanced collections expired proposal',
426 => 'Upgrade required',
428 => 'Precondition Required',
429 => 'Too Many Requests',
431 => 'Request Header Fields Too Large',
500 => 'Internal Server Error',
501 => 'Not Implemented',
502 => 'Bad Gateway',
503 => 'Service Unavailable',
504 => 'Gateway Timeout',
505 => 'HTTP Version Not Supported',
506 => 'Variant Also Negotiates (Experimental)',
507 => 'Insufficient Storage',
508 => 'Loop Detected',
510 => 'Not Extended',
511 => 'Network Authentication Required',
);
/**
* @param int $code 状态码
* @param double $duration 请求时长
* @param array $headers 响应头部
* @param string $body 响应内容
* @param string $error 错误描述
*/
public function __construct($code, $duration, array $headers = array(), $body = null, $error = null)
{
$this->statusCode = $code;
$this->duration = $duration;
$this->headers = $headers;
$this->body = $body;
$this->error = $error;
$this->jsonData = null;
if ($error !== null) {
return;
}
if ($body === null) {
if ($code >= 400) {
$this->error = self::$statusTexts[$code];
}
return;
}
if (self::isJson($headers)) {
try {
$jsonData = self::bodyJson($body);
if ($code >= 400) {
$this->error = $body;
if ($jsonData['error'] !== null) {
$this->error = $jsonData['error'];
}
}
$this->jsonData = $jsonData;
} catch (\InvalidArgumentException $e) {
$this->error = $body;
if ($code >= 200 && $code < 300) {
$this->error = $e->getMessage();
}
}
} elseif ($code >= 400) {
$this->error = $body;
}
return;
}
public function json()
{
return $this->jsonData;
}
private static function bodyJson($body)
{
return \Qiniu\json_decode((string) $body, true, 512);
}
public function xVia()
{
$via = $this->headers['X-Via'];
if ($via === null) {
$via = $this->headers['X-Px'];
}
if ($via === null) {
$via = $this->headers['Fw-Via'];
}
return $via;
}
public function xLog()
{
return $this->headers['X-Log'];
}
public function xReqId()
{
return $this->headers['X-Reqid'];
}
public function ok()
{
return $this->statusCode >= 200 && $this->statusCode < 300 && $this->error === null;
}
public function needRetry()
{
$code = $this->statusCode;
if ($code < 0 || ($code / 100 === 5 and $code !== 579) || $code === 996) {
return true;
}
}
private static function isJson($headers)
{
return array_key_exists('Content-Type', $headers) &&
strpos($headers['Content-Type'], 'application/json') === 0;
}
}

View File

@@ -0,0 +1,282 @@
<?php
namespace Qiniu\Processing;
use Qiniu;
/**
* 主要涉及图片链接拼接
*
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/imageview2.html
*/
final class ImageUrlBuilder
{
/**
* mode合法范围值
*
* @var array
*/
protected $modeArr = array(0, 1, 2, 3, 4, 5);
/**
* format合法值
*
* @var array
*/
protected $formatArr = array('psd', 'jpeg', 'png', 'gif', 'webp', 'tiff', 'bmp');
/**
* 水印图片位置合法值
*
* @var array
*/
protected $gravityArr = array('NorthWest', 'North', 'NorthEast',
'West', 'Center', 'East', 'SouthWest', 'South', 'SouthEast');
/**
* 缩略图链接拼接
*
* @param string $url 图片链接
* @param int $mode 缩略模式
* @param int $width 宽度
* @param int $height 长度
* @param string $format 输出类型
* @param int $quality 图片质量
* @param int $interlace 是否支持渐进显示
* @param int $ignoreError 忽略结果
* @return string
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/imageview2.html
* @author Sherlock Ren <sherlock_ren@icloud.com>
*/
public function thumbnail(
$url,
$mode,
$width,
$height,
$format = null,
$interlace = null,
$quality = null,
$ignoreError = 1
) {
// url合法效验
if (!$this->isUrl($url)) {
return $url;
}
// 参数合法性效验
if (!in_array(intval($mode), $this->modeArr, true)) {
return $url;
}
if (!$width || !$height) {
return $url;
}
$thumbStr = 'imageView2/' . $mode . '/w/' . $width . '/h/' . $height . '/';
// 拼接输出格式
if (!is_null($format)
&& in_array($format, $this->formatArr)
) {
$thumbStr .= 'format/' . $format . '/';
}
// 拼接渐进显示
if (!is_null($interlace)
&& in_array(intval($interlace), array(0, 1), true)
) {
$thumbStr .= 'interlace/' . $interlace . '/';
}
// 拼接图片质量
if (!is_null($quality)
&& intval($quality) >= 0
&& intval($quality) <= 100
) {
$thumbStr .= 'q/' . $quality . '/';
}
$thumbStr .= 'ignore-error/' . $ignoreError . '/';
// 如果有query_string用|线分割实现多参数
return $url . ($this->hasQuery($url) ? '|' : '?') . $thumbStr;
}
/**
* 图片水印
*
* @param string $url 图片链接
* @param string $image 水印图片链接
* @param numeric $dissolve 透明度
* @param string $gravity 水印位置
* @param numeric $dx 横轴边距
* @param numeric $dy 纵轴边距
* @param numeric $watermarkScale 自适应原图的短边比例
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html
* @return string
* @author Sherlock Ren <sherlock_ren@icloud.com>
*/
public function waterImg(
$url,
$image,
$dissolve = 100,
$gravity = 'SouthEast',
$dx = null,
$dy = null,
$watermarkScale = null
) {
// url合法效验
if (!$this->isUrl($url)) {
return $url;
}
$waterStr = 'watermark/1/image/' . \Qiniu\base64_urlSafeEncode($image) . '/';
// 拼接水印透明度
if (is_numeric($dissolve)
&& $dissolve <= 100
) {
$waterStr .= 'dissolve/' . $dissolve . '/';
}
// 拼接水印位置
if (in_array($gravity, $this->gravityArr, true)) {
$waterStr .= 'gravity/' . $gravity . '/';
}
// 拼接横轴边距
if (!is_null($dx)
&& is_numeric($dx)
) {
$waterStr .= 'dx/' . $dx . '/';
}
// 拼接纵轴边距
if (!is_null($dy)
&& is_numeric($dy)
) {
$waterStr .= 'dy/' . $dy . '/';
}
// 拼接自适应原图的短边比例
if (!is_null($watermarkScale)
&& is_numeric($watermarkScale)
&& $watermarkScale > 0
&& $watermarkScale < 1
) {
$waterStr .= 'ws/' . $watermarkScale . '/';
}
// 如果有query_string用|线分割实现多参数
return $url . ($this->hasQuery($url) ? '|' : '?') . $waterStr;
}
/**
* 文字水印
*
* @param string $url 图片链接
* @param string $text 文字
* @param string $font 文字字体
* @param string $fontSize 文字字号
* @param string $fontColor 文字颜色
* @param numeric $dissolve 透明度
* @param string $gravity 水印位置
* @param numeric $dx 横轴边距
* @param numeric $dy 纵轴边距
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html#text-watermark
* @return string
* @author Sherlock Ren <sherlock_ren@icloud.com>
*/
public function waterText(
$url,
$text,
$font = '黑体',
$fontSize = 0,
$fontColor = null,
$dissolve = 100,
$gravity = 'SouthEast',
$dx = null,
$dy = null
) {
// url合法效验
if (!$this->isUrl($url)) {
return $url;
}
$waterStr = 'watermark/2/text/'
. \Qiniu\base64_urlSafeEncode($text) . '/font/'
. \Qiniu\base64_urlSafeEncode($font) . '/';
// 拼接文字大小
if (is_int($fontSize)) {
$waterStr .= 'fontsize/' . $fontSize . '/';
}
// 拼接文字颜色
if (!is_null($fontColor)
&& $fontColor
) {
$waterStr .= 'fill/' . \Qiniu\base64_urlSafeEncode($fontColor) . '/';
}
// 拼接水印透明度
if (is_numeric($dissolve)
&& $dissolve <= 100
) {
$waterStr .= 'dissolve/' . $dissolve . '/';
}
// 拼接水印位置
if (in_array($gravity, $this->gravityArr, true)) {
$waterStr .= 'gravity/' . $gravity . '/';
}
// 拼接横轴边距
if (!is_null($dx)
&& is_numeric($dx)
) {
$waterStr .= 'dx/' . $dx . '/';
}
// 拼接纵轴边距
if (!is_null($dy)
&& is_numeric($dy)
) {
$waterStr .= 'dy/' . $dy . '/';
}
// 如果有query_string用|线分割实现多参数
return $url . ($this->hasQuery($url) ? '|' : '?') . $waterStr;
}
/**
* 效验url合法性
*
* @param string $url url链接
* @return string
* @author Sherlock Ren <sherlock_ren@icloud.com>
*/
protected function isUrl($url)
{
$urlArr = parse_url($url);
return $urlArr['scheme']
&& in_array($urlArr['scheme'], array('http', 'https'))
&& $urlArr['host']
&& $urlArr['path'];
}
/**
* 检测是否有query
*
* @param string $url url链接
* @return string
* @author Sherlock Ren <sherlock_ren@icloud.com>
*/
protected function hasQuery($url)
{
$urlArr = parse_url($url);
return !empty($urlArr['query']);
}
}

View File

@@ -0,0 +1,60 @@
<?php
namespace Qiniu\Processing;
use Qiniu\Http\Client;
use Qiniu\Http\Error;
final class Operation
{
private $auth;
private $token_expire;
private $domain;
public function __construct($domain, $auth = null, $token_expire = 3600)
{
$this->auth = $auth;
$this->domain = $domain;
$this->token_expire = $token_expire;
}
/**
* 对资源文件进行处理
*
* @param $key 待处理的资源文件名
* @param $fops string|array fop操作多次fop操作以array的形式传入。
* eg. imageView2/1/w/200/h/200, imageMogr2/thumbnail/!75px
*
* @return array 文件处理后的结果及错误。
*
* @link http://developer.qiniu.com/docs/v6/api/reference/fop/
*/
public function execute($key, $fops)
{
$url = $this->buildUrl($key, $fops);
$resp = Client::get($url);
if (!$resp->ok()) {
return array(null, new Error($url, $resp));
}
if ($resp->json() !== null) {
return array($resp->json(), null);
}
return array($resp->body, null);
}
public function buildUrl($key, $fops, $protocol = 'http')
{
if (is_array($fops)) {
$fops = implode('|', $fops);
}
$url = $protocol . "://$this->domain/$key?$fops";
if ($this->auth !== null) {
$url = $this->auth->privateDownloadUrl($url, $this->token_expire);
}
return $url;
}
}

View File

@@ -0,0 +1,94 @@
<?php
namespace Qiniu\Processing;
use Qiniu\Config;
use Qiniu\Http\Client;
use Qiniu\Http\Error;
use Qiniu\Processing\Operation;
/**
* 持久化处理类,该类用于主动触发异步持久化操作.
*
* @link http://developer.qiniu.com/docs/v6/api/reference/fop/pfop/pfop.html
*/
final class PersistentFop
{
/**
* @var 账号管理密钥对Auth对象
*/
private $auth;
/*
* @var 配置对象Config 对象
* */
private $config;
public function __construct($auth, $config = null)
{
$this->auth = $auth;
if ($config == null) {
$this->config = new Config();
} else {
$this->config = $config;
}
}
/**
* 对资源文件进行异步持久化处理
* @param $bucket 资源所在空间
* @param $key 待处理的源文件
* @param $fops string|array 待处理的pfop操作多个pfop操作以array的形式传入。
* eg. avthumb/mp3/ab/192k, vframe/jpg/offset/7/w/480/h/360
* @param $pipeline 资源处理队列
* @param $notify_url 处理结果通知地址
* @param $force 是否强制执行一次新的指令
*
*
* @return array 返回持久化处理的persistentId, 和返回的错误。
*
* @link http://developer.qiniu.com/docs/v6/api/reference/fop/
*/
public function execute($bucket, $key, $fops, $pipeline = null, $notify_url = null, $force = false)
{
if (is_array($fops)) {
$fops = implode(';', $fops);
}
$params = array('bucket' => $bucket, 'key' => $key, 'fops' => $fops);
\Qiniu\setWithoutEmpty($params, 'pipeline', $pipeline);
\Qiniu\setWithoutEmpty($params, 'notifyURL', $notify_url);
if ($force) {
$params['force'] = 1;
}
$data = http_build_query($params);
$scheme = "http://";
if ($this->config->useHTTPS === true) {
$scheme = "https://";
}
$url = $scheme . Config::API_HOST . '/pfop/';
$headers = $this->auth->authorization($url, $data, 'application/x-www-form-urlencoded');
$headers['Content-Type'] = 'application/x-www-form-urlencoded';
$response = Client::post($url, $data, $headers);
if (!$response->ok()) {
return array(null, new Error($url, $response));
}
$r = $response->json();
$id = $r['persistentId'];
return array($id, null);
}
public function status($id)
{
$scheme = "http://";
if ($this->config->useHTTPS === true) {
$scheme = "https://";
}
$url = $scheme . Config::API_HOST . "/status/get/prefop?id=$id";
$response = Client::get($url);
if (!$response->ok()) {
return array(null, new Error($url, $response));
}
return array($response->json(), null);
}
}

View File

@@ -0,0 +1,204 @@
<?php
namespace Qiniu\Rtc;
use Qiniu\Http\Client;
use Qiniu\Http\Error;
use Qiniu\Config;
use Qiniu\Auth;
class AppClient
{
private $auth;
private $baseURL;
public function __construct(Auth $auth)
{
$this->auth = $auth;
$this->baseURL = sprintf("%s/%s/apps", Config::RTCAPI_HOST, Config::RTCAPI_VERSION);
}
/*
* hub: 直播空间名
* title: app 的名称 注意Title 不是唯一标识,重复 create 动作将生成多个 app
* maxUsers人数限制
* NoAutoKickUser: bool 类型,可选,禁止自动踢人(抢流)。默认为 false
即同一个身份的 client (app/room/user) ,新的连麦请求可以成功,旧连接被关闭。
*/
public function createApp($hub, $title, $maxUsers = null, $noAutoKickUser = null)
{
$params['hub'] = $hub;
$params['title'] = $title;
if (!empty($maxUsers)) {
$params['maxUsers'] = $maxUsers;
}
if (!empty($noAutoKickUser)) {
$params['noAutoKickUser'] = $noAutoKickUser;
}
$body = json_encode($params);
$ret = $this->post($this->baseURL, $body);
return $ret;
}
/*
* appId: app 的唯一标识,创建的时候由系统生成。
* Title: app 的名称, 可选。
* Hub: 绑定的直播 hub可选用于合流后 rtmp 推流。
* MaxUsers: int 类型,可选,连麦房间支持的最大在线人数。
* NoAutoKickUser: bool 类型,可选,禁止自动踢人。
* MergePublishRtmp: 连麦合流转推 RTMP 的配置,可选择。其详细配置包括如下
Enable: 布尔类型,用于开启和关闭所有房间的合流功能。
AudioOnly: 布尔类型,可选,指定是否只合成音频。
Height, Width: int64可选指定合流输出的高和宽默认为 640 x 480。
OutputFps: int64可选指定合流输出的帧率默认为 25 fps 。
OutputKbps: int64可选指定合流输出的码率默认为 1000 。
URL: 合流后转推旁路直播的地址,可选,支持魔法变量配置按照连麦房间号生成不同的推流地址。如果是转推到七牛直播云,不建议使用该配置。
StreamTitle: 转推七牛直播云的流名,可选,支持魔法变量配置按照连麦房间号生成不同的流名。例如,配置 Hub 为 qn-zhibo ,配置 StreamTitle 为 $(roomName) ,则房间 meeting-001 的合流将会被转推到 rtmp://pili-publish.qn-zhibo.***.com/qn-zhibo/meeting-001地址。详细配置细则请咨询七牛技术支持。
*/
public function updateApp($appId, $hub, $title, $maxUsers = null, $mergePublishRtmp = null, $noAutoKickUser = null)
{
$url = $this->baseURL . '/' . $appId;
$params['hub'] = $hub;
$params['title'] = $title;
if (!empty($maxUsers)) {
$params['maxUsers'] = $maxUsers;
}
if (!empty($noAutoKickUser)) {
$params['noAutoKickUser'] = $noAutoKickUser;
}
if (!empty($mergePublishRtmp)) {
$params['mergePublishRtmp'] = $mergePublishRtmp;
}
$body = json_encode($params);
$ret = $this->post($url, $body);
return $ret;
}
/*
* appId: app 的唯一标识,创建的时候由系统生成。
*/
public function getApp($appId)
{
$url = $this->baseURL . '/' . $appId;
$ret = $this->get($url);
return $ret;
}
/*
* appId: app 的唯一标识,创建的时候由系统生成
*/
public function deleteApp($appId)
{
$url = $this->baseURL . '/' . $appId;
list(, $err) = $this->delete($url);
return $err;
}
/*
* 获取房间的人数
* appId: app 的唯一标识,创建的时候由系统生成。
* roomName: 操作所查询的连麦房间。
*/
public function listUser($appId, $roomName)
{
$url = sprintf("%s/%s/rooms/%s/users", $this->baseURL, $appId, $roomName);
$ret = $this->get($url);
return $ret;
}
/*
* 踢出玩家
* appId: app 的唯一标识,创建的时候由系统生成。
* roomName: 连麦房间
* userId: 请求加入房间的用户ID
*/
public function kickUser($appId, $roomName, $userId)
{
$url = sprintf("%s/%s/rooms/%s/users/%s", $this->baseURL, $appId, $roomName, $userId);
list(, $err) = $this->delete($url);
return $err;
}
/*
* 获取房间的人数
* appId: app 的唯一标识,创建的时候由系统生成。
* prefix: 所查询房间名的前缀索引,可以为空。
* offset: int 类型,分页查询的位移标记。
* limit: int 类型,此次查询的最大长度。
* GET /v3/apps/<AppID>/rooms?prefix=<RoomNamePrefix>&offset=<Offset>&limit=<Limit>
*/
public function listActiveRooms($appId, $prefix = null, $offset = null, $limit = null)
{
if (isset($prefix)) {
$query['prefix'] = $prefix;
}
if (isset($offset)) {
$query['offset'] = $offset;
}
if (isset($limit)) {
$query['limit'] = $limit;
}
if (isset($query) && !empty($query)) {
$query = '?' . http_build_query($query);
$url = sprintf("%s/%s/rooms%s", $this->baseURL, $appId, $query);
} else {
$url = sprintf("%s/%s/rooms", $this->baseURL, $appId);
}
$ret = $this->get($url);
return $ret;
}
/*
* appId: app 的唯一标识,创建的时候由系统生成。
* roomName: 房间名称,需满足规格 ^[a-zA-Z0-9_-]{3,64}$
* userId: 请求加入房间的用户 ID需满足规格 ^[a-zA-Z0-9_-]{3,50}$
* expireAt: int64 类型鉴权的有效时间传入以秒为单位的64位Unix
绝对时间token 将在该时间后失效。
* permission: 该用户的房间管理权限,"admin" 或 "user",默认为 "user" 。
当权限角色为 "admin" 时,拥有将其他用户移除出房间等特权.
*/
public function appToken($appId, $roomName, $userId, $expireAt, $permission)
{
$params['appId'] = $appId;
$params['userId'] = $userId;
$params['roomName'] = $roomName;
$params['permission'] = $permission;
$params['expireAt'] = $expireAt;
$appAccessString = json_encode($params);
return $this->auth->signWithData($appAccessString);
}
private function get($url, $cType = null)
{
$rtcToken = $this->auth->authorizationV2($url, "GET", null, $cType);
$rtcToken['Content-Type'] = $cType;
$ret = Client::get($url, $rtcToken);
if (!$ret->ok()) {
return array(null, new Error($url, $ret));
}
return array($ret->json(), null);
}
private function delete($url, $contentType = 'application/json')
{
$rtcToken = $this->auth->authorizationV2($url, "DELETE", null, $contentType);
$rtcToken['Content-Type'] = $contentType;
$ret = Client::delete($url, $rtcToken);
if (!$ret->ok()) {
return array(null, new Error($url, $ret));
}
return array($ret->json(), null);
}
private function post($url, $body, $contentType = 'application/json')
{
$rtcToken = $this->auth->authorizationV2($url, "POST", $body, $contentType);
$rtcToken['Content-Type'] = $contentType;
$ret = Client::post($url, $body, $rtcToken);
if (!$ret->ok()) {
return array(null, new Error($url, $ret));
}
$r = ($ret->body === null) ? array() : $ret->json();
return array($r, null);
}
}

View File

@@ -0,0 +1,73 @@
<?php
namespace Qiniu\Storage;
use Qiniu\Auth;
use Qiniu\Config;
use Qiniu\Zone;
use Qiniu\Http\Client;
use Qiniu\Http\Error;
/**
* 主要涉及了鉴黄接口的实现,具体的接口规格可以参考
*
* @link https://developer.qiniu.com/dora/manual/3674/kodo-product-introduction
*/
final class ArgusManager
{
private $auth;
private $config;
public function __construct(Auth $auth, Config $config = null)
{
$this->auth = $auth;
if ($config == null) {
$this->config = new Config();
} else {
$this->config = $config;
}
}
/**
* 视频鉴黄
*
* @param $body body信息
* @param $vid videoID
*
* @return mixed 成功返回NULL失败返回对象Qiniu\Http\Error
* @link https://developer.qiniu.com/dora/manual/4258/video-pulp
*/
public function pulpVideo($body, $vid)
{
$path = '/v1/video/' . $vid;
return $this->arPost($path, $body);
}
private function getArHost()
{
$scheme = "http://";
if ($this->config->useHTTPS == true) {
$scheme = "https://";
}
return $scheme . Config::ARGUS_HOST;
}
private function arPost($path, $body = null)
{
$url = $this->getArHost() . $path;
return $this->post($url, $body);
}
private function post($url, $body)
{
$headers = $this->auth->authorizationV2($url, 'POST', $body, 'application/json');
$headers['Content-Type']='application/json';
$ret = Client::post($url, $body, $headers);
if (!$ret->ok()) {
print($ret->statusCode);
return array(null, new Error($url, $ret));
}
$r = ($ret->body === null) ? array() : $ret->json();
return array($r, null);
}
}

View File

@@ -0,0 +1,492 @@
<?php
namespace Qiniu\Storage;
use Qiniu\Auth;
use Qiniu\Config;
use Qiniu\Zone;
use Qiniu\Http\Client;
use Qiniu\Http\Error;
/**
* 主要涉及了空间资源管理及批量操作接口的实现,具体的接口规格可以参考
*
* @link https://developer.qiniu.com/kodo/api/1274/rs
*/
final class BucketManager
{
private $auth;
private $config;
public function __construct(Auth $auth, Config $config = null)
{
$this->auth = $auth;
if ($config == null) {
$this->config = new Config();
} else {
$this->config = $config;
}
}
/**
* 获取指定账号下所有的空间名。
*
* @return string[] 包含所有空间名
*/
public function buckets($shared = true)
{
$includeShared = "false";
if ($shared === true) {
$includeShared = "true";
}
return $this->rsGet('/buckets?shared=' . $includeShared);
}
/**
* 获取指定空间绑定的所有的域名
*
* @return string[] 包含所有空间域名
*/
public function domains($bucket)
{
return $this->apiGet('/v6/domain/list?tbl=' . $bucket);
}
/**
* 获取空间绑定的域名列表
* @return string[] 包含空间绑定的所有域名
*/
/**
* 列取空间的文件列表
*
* @param $bucket 空间名
* @param $prefix 列举前缀
* @param $marker 列举标识符
* @param $limit 单次列举个数限制
* @param $delimiter 指定目录分隔符
*
* @return array 包含文件信息的数组,类似:[
* {
* "hash" => "<Hash string>",
* "key" => "<Key string>",
* "fsize" => "<file size>",
* "putTime" => "<file modify time>"
* },
* ...
* ]
* @link http://developer.qiniu.com/docs/v6/api/reference/rs/list.html
*/
public function listFiles($bucket, $prefix = null, $marker = null, $limit = 1000, $delimiter = null)
{
$query = array('bucket' => $bucket);
\Qiniu\setWithoutEmpty($query, 'prefix', $prefix);
\Qiniu\setWithoutEmpty($query, 'marker', $marker);
\Qiniu\setWithoutEmpty($query, 'limit', $limit);
\Qiniu\setWithoutEmpty($query, 'delimiter', $delimiter);
$url = $this->getRsfHost() . '/list?' . http_build_query($query);
return $this->get($url);
}
/**
* 获取资源的元信息,但不返回文件内容
*
* @param $bucket 待获取信息资源所在的空间
* @param $key 待获取资源的文件名
*
* @return array 包含文件信息的数组,类似:
* [
* "hash" => "<Hash string>",
* "key" => "<Key string>",
* "fsize" => <file size>,
* "putTime" => "<file modify time>"
* "fileType" => <file type>
* ]
*
* @link http://developer.qiniu.com/docs/v6/api/reference/rs/stat.html
*/
public function stat($bucket, $key)
{
$path = '/stat/' . \Qiniu\entry($bucket, $key);
return $this->rsGet($path);
}
/**
* 删除指定资源
*
* @param $bucket 待删除资源所在的空间
* @param $key 待删除资源的文件名
*
* @return mixed 成功返回NULL失败返回对象Qiniu\Http\Error
* @link http://developer.qiniu.com/docs/v6/api/reference/rs/delete.html
*/
public function delete($bucket, $key)
{
$path = '/delete/' . \Qiniu\entry($bucket, $key);
list(, $error) = $this->rsPost($path);
return $error;
}
/**
* 给资源进行重命名本质为move操作。
*
* @param $bucket 待操作资源所在空间
* @param $oldname 待操作资源文件名
* @param $newname 目标资源文件名
*
* @return mixed 成功返回NULL失败返回对象Qiniu\Http\Error
*/
public function rename($bucket, $oldname, $newname)
{
return $this->move($bucket, $oldname, $bucket, $newname);
}
/**
* 给资源进行重命名本质为move操作。
*
* @param $from_bucket 待操作资源所在空间
* @param $from_key 待操作资源文件名
* @param $to_bucket 目标资源空间名
* @param $to_key 目标资源文件名
*
* @return mixed 成功返回NULL失败返回对象Qiniu\Http\Error
* @link http://developer.qiniu.com/docs/v6/api/reference/rs/copy.html
*/
public function copy($from_bucket, $from_key, $to_bucket, $to_key, $force = false)
{
$from = \Qiniu\entry($from_bucket, $from_key);
$to = \Qiniu\entry($to_bucket, $to_key);
$path = '/copy/' . $from . '/' . $to;
if ($force === true) {
$path .= '/force/true';
}
list(, $error) = $this->rsPost($path);
return $error;
}
/**
* 将资源从一个空间到另一个空间
*
* @param $from_bucket 待操作资源所在空间
* @param $from_key 待操作资源文件名
* @param $to_bucket 目标资源空间名
* @param $to_key 目标资源文件名
*
* @return mixed 成功返回NULL失败返回对象Qiniu\Http\Error
* @link http://developer.qiniu.com/docs/v6/api/reference/rs/move.html
*/
public function move($from_bucket, $from_key, $to_bucket, $to_key, $force = false)
{
$from = \Qiniu\entry($from_bucket, $from_key);
$to = \Qiniu\entry($to_bucket, $to_key);
$path = '/move/' . $from . '/' . $to;
if ($force) {
$path .= '/force/true';
}
list(, $error) = $this->rsPost($path);
return $error;
}
/**
* 主动修改指定资源的文件类型
*
* @param $bucket 待操作资源所在空间
* @param $key 待操作资源文件名
* @param $mime 待操作文件目标mimeType
*
* @return mixed 成功返回NULL失败返回对象Qiniu\Http\Error
* @link http://developer.qiniu.com/docs/v6/api/reference/rs/chgm.html
*/
public function changeMime($bucket, $key, $mime)
{
$resource = \Qiniu\entry($bucket, $key);
$encode_mime = \Qiniu\base64_urlSafeEncode($mime);
$path = '/chgm/' . $resource . '/mime/' . $encode_mime;
list(, $error) = $this->rsPost($path);
return $error;
}
/**
* 修改指定资源的存储类型
*
* @param $bucket 待操作资源所在空间
* @param $key 待操作资源文件名
* @param $fileType 待操作文件目标文件类型
*
* @return mixed 成功返回NULL失败返回对象Qiniu\Http\Error
* @link https://developer.qiniu.com/kodo/api/3710/modify-the-file-type
*/
public function changeType($bucket, $key, $fileType)
{
$resource = \Qiniu\entry($bucket, $key);
$path = '/chtype/' . $resource . '/type/' . $fileType;
list(, $error) = $this->rsPost($path);
return $error;
}
/**
* 修改文件的存储状态,即禁用状态和启用状态间的的互相转换
*
* @param $bucket 待操作资源所在空间
* @param $key 待操作资源文件名
* @param $status 待操作文件目标文件类型
*
* @return mixed 成功返回NULL失败返回对象Qiniu\Http\Error
* @link https://developer.qiniu.com/kodo/api/4173/modify-the-file-status
*/
public function changeStatus($bucket, $key, $status)
{
$resource = \Qiniu\entry($bucket, $key);
$path = '/chstatus/' . $resource . '/status/' . $status;
list(, $error) = $this->rsPost($path);
return $error;
}
/**
* 从指定URL抓取资源并将该资源存储到指定空间中
*
* @param $url 指定的URL
* @param $bucket 目标资源空间
* @param $key 目标资源文件名
*
* @return array 包含已拉取的文件信息。
* 成功时: [
* [
* "hash" => "<Hash string>",
* "key" => "<Key string>"
* ],
* null
* ]
*
* 失败时: [
* null,
* Qiniu/Http/Error
* ]
* @link http://developer.qiniu.com/docs/v6/api/reference/rs/fetch.html
*/
public function fetch($url, $bucket, $key = null)
{
$resource = \Qiniu\base64_urlSafeEncode($url);
$to = \Qiniu\entry($bucket, $key);
$path = '/fetch/' . $resource . '/to/' . $to;
$ak = $this->auth->getAccessKey();
$ioHost = $this->config->getIovipHost($ak, $bucket);
$url = $ioHost . $path;
return $this->post($url, null);
}
/**
* 从镜像源站抓取资源到空间中,如果空间中已经存在,则覆盖该资源
*
* @param $bucket 待获取资源所在的空间
* @param $key 代获取资源文件名
*
* @return mixed 成功返回NULL失败返回对象Qiniu\Http\Error
* @link http://developer.qiniu.com/docs/v6/api/reference/rs/prefetch.html
*/
public function prefetch($bucket, $key)
{
$resource = \Qiniu\entry($bucket, $key);
$path = '/prefetch/' . $resource;
$ak = $this->auth->getAccessKey();
$ioHost = $this->config->getIovipHost($ak, $bucket);
$url = $ioHost . $path;
list(, $error) = $this->post($url, null);
return $error;
}
/**
* 在单次请求中进行多个资源管理操作
*
* @param $operations 资源管理操作数组
*
* @return array 每个资源的处理情况,结果类似:
* [
* { "code" => <HttpCode int>, "data" => <Data> },
* { "code" => <HttpCode int> },
* { "code" => <HttpCode int> },
* { "code" => <HttpCode int> },
* { "code" => <HttpCode int>, "data" => { "error": "<ErrorMessage string>" } },
* ...
* ]
* @link http://developer.qiniu.com/docs/v6/api/reference/rs/batch.html
*/
public function batch($operations)
{
$params = 'op=' . implode('&op=', $operations);
return $this->rsPost('/batch', $params);
}
/**
* 设置文件的生命周期
*
* @param $bucket 设置文件生命周期文件所在的空间
* @param $key 设置文件生命周期文件的文件名
* @param $days 设置该文件多少天后删除,当$days设置为0时表示取消该文件的生命周期
*
* @return Mixed
* @link https://developer.qiniu.com/kodo/api/update-file-lifecycle
*/
public function deleteAfterDays($bucket, $key, $days)
{
$entry = \Qiniu\entry($bucket, $key);
$path = "/deleteAfterDays/$entry/$days";
list(, $error) = $this->rsPost($path);
return $error;
}
private function getRsfHost()
{
$scheme = "http://";
if ($this->config->useHTTPS == true) {
$scheme = "https://";
}
return $scheme . Config::RSF_HOST;
}
private function getRsHost()
{
$scheme = "http://";
if ($this->config->useHTTPS == true) {
$scheme = "https://";
}
return $scheme . Config::RS_HOST;
}
private function getApiHost()
{
$scheme = "http://";
if ($this->config->useHTTPS == true) {
$scheme = "https://";
}
return $scheme . Config::API_HOST;
}
private function rsPost($path, $body = null)
{
$url = $this->getRsHost() . $path;
return $this->post($url, $body);
}
private function apiGet($path)
{
$url = $this->getApiHost() . $path;
return $this->get($url);
}
private function rsGet($path)
{
$url = $this->getRsHost() . $path;
return $this->get($url);
}
private function get($url)
{
$headers = $this->auth->authorization($url);
$ret = Client::get($url, $headers);
if (!$ret->ok()) {
return array(null, new Error($url, $ret));
}
return array($ret->json(), null);
}
private function post($url, $body)
{
$headers = $this->auth->authorization($url, $body, 'application/x-www-form-urlencoded');
$ret = Client::post($url, $body, $headers);
if (!$ret->ok()) {
return array(null, new Error($url, $ret));
}
$r = ($ret->body === null) ? array() : $ret->json();
return array($r, null);
}
public static function buildBatchCopy($source_bucket, $key_pairs, $target_bucket, $force)
{
return self::twoKeyBatch('/copy', $source_bucket, $key_pairs, $target_bucket, $force);
}
public static function buildBatchRename($bucket, $key_pairs, $force)
{
return self::buildBatchMove($bucket, $key_pairs, $bucket, $force);
}
public static function buildBatchMove($source_bucket, $key_pairs, $target_bucket, $force)
{
return self::twoKeyBatch('/move', $source_bucket, $key_pairs, $target_bucket, $force);
}
public static function buildBatchDelete($bucket, $keys)
{
return self::oneKeyBatch('/delete', $bucket, $keys);
}
public static function buildBatchStat($bucket, $keys)
{
return self::oneKeyBatch('/stat', $bucket, $keys);
}
public static function buildBatchDeleteAfterDays($bucket, $key_day_pairs)
{
$data = array();
foreach ($key_day_pairs as $key => $day) {
array_push($data, '/deleteAfterDays/' . \Qiniu\entry($bucket, $key) . '/' . $day);
}
return $data;
}
public static function buildBatchChangeMime($bucket, $key_mime_pairs)
{
$data = array();
foreach ($key_mime_pairs as $key => $mime) {
array_push($data, '/chgm/' . \Qiniu\entry($bucket, $key) . '/mime/' . base64_encode($mime));
}
return $data;
}
public static function buildBatchChangeType($bucket, $key_type_pairs)
{
$data = array();
foreach ($key_type_pairs as $key => $type) {
array_push($data, '/chtype/' . \Qiniu\entry($bucket, $key) . '/type/' . $type);
}
return $data;
}
private static function oneKeyBatch($operation, $bucket, $keys)
{
$data = array();
foreach ($keys as $key) {
array_push($data, $operation . '/' . \Qiniu\entry($bucket, $key));
}
return $data;
}
private static function twoKeyBatch($operation, $source_bucket, $key_pairs, $target_bucket, $force)
{
if ($target_bucket === null) {
$target_bucket = $source_bucket;
}
$data = array();
$forceOp = "false";
if ($force) {
$forceOp = "true";
}
foreach ($key_pairs as $from_key => $to_key) {
$from = \Qiniu\entry($source_bucket, $from_key);
$to = \Qiniu\entry($target_bucket, $to_key);
array_push($data, $operation . '/' . $from . '/' . $to . "/force/" . $forceOp);
}
return $data;
}
}

View File

@@ -0,0 +1,139 @@
<?php
namespace Qiniu\Storage;
use Qiniu\Http\Client;
use Qiniu\Http\Error;
final class FormUploader
{
/**
* 上传二进制流到七牛, 内部使用
*
* @param $upToken 上传凭证
* @param $key 上传文件名
* @param $data 上传二进制流
* @param $config 上传配置
* @param $params 自定义变量,规格参考
* http://developer.qiniu.com/docs/v6/api/overview/up/response/vars.html#xvar
* @param $mime 上传数据的mimeType
*
* @return array 包含已上传文件的信息,类似:
* [
* "hash" => "<Hash string>",
* "key" => "<Key string>"
* ]
*/
public static function put(
$upToken,
$key,
$data,
$config,
$params,
$mime,
$fname
) {
$fields = array('token' => $upToken);
if ($key === null) {
$fname='nullkey';
} else {
$fields['key'] = $key;
}
//enable crc32 check by default
$fields['crc32'] = \Qiniu\crc32_data($data);
if ($params) {
foreach ($params as $k => $v) {
$fields[$k] = $v;
}
}
list($accessKey, $bucket, $err) = \Qiniu\explodeUpToken($upToken);
if ($err != null) {
return array(null, $err);
}
$upHost = $config->getUpHost($accessKey, $bucket);
$response = Client::multipartPost($upHost, $fields, 'file', $fname, $data, $mime);
if (!$response->ok()) {
return array(null, new Error($upHost, $response));
}
return array($response->json(), null);
}
/**
* 上传文件到七牛,内部使用
*
* @param $upToken 上传凭证
* @param $key 上传文件名
* @param $filePath 上传文件的路径
* @param $config 上传配置
* @param $params 自定义变量,规格参考
* http://developer.qiniu.com/docs/v6/api/overview/up/response/vars.html#xvar
* @param $mime 上传数据的mimeType
*
* @return array 包含已上传文件的信息,类似:
* [
* "hash" => "<Hash string>",
* "key" => "<Key string>"
* ]
*/
public static function putFile(
$upToken,
$key,
$filePath,
$config,
$params,
$mime
) {
$fields = array('token' => $upToken, 'file' => self::createFile($filePath, $mime));
if ($key !== null) {
$fields['key'] = $key;
}
$fields['crc32'] = \Qiniu\crc32_file($filePath);
if ($params) {
foreach ($params as $k => $v) {
$fields[$k] = $v;
}
}
$fields['key'] = $key;
$headers = array('Content-Type' => 'multipart/form-data');
list($accessKey, $bucket, $err) = \Qiniu\explodeUpToken($upToken);
if ($err != null) {
return array(null, $err);
}
$upHost = $config->getUpHost($accessKey, $bucket);
$response = Client::post($upHost, $fields, $headers);
if (!$response->ok()) {
return array(null, new Error($upHost, $response));
}
return array($response->json(), null);
}
private static function createFile($filename, $mime)
{
// PHP 5.5 introduced a CurlFile object that deprecates the old @filename syntax
// See: https://wiki.php.net/rfc/curl-file-upload
if (function_exists('curl_file_create')) {
return curl_file_create($filename, $mime);
}
// Use the old style if using an older version of PHP
$value = "@{$filename}";
if (!empty($mime)) {
$value .= ';type=' . $mime;
}
return $value;
}
}

View File

@@ -0,0 +1,169 @@
<?php
namespace Qiniu\Storage;
use Qiniu\Config;
use Qiniu\Http\Client;
use Qiniu\Http\Error;
/**
* 断点续上传类, 该类主要实现了断点续上传中的分块上传,
* 以及相应地创建块和创建文件过程.
*
* @link http://developer.qiniu.com/docs/v6/api/reference/up/mkblk.html
* @link http://developer.qiniu.com/docs/v6/api/reference/up/mkfile.html
*/
final class ResumeUploader
{
private $upToken;
private $key;
private $inputStream;
private $size;
private $params;
private $mime;
private $contexts;
private $host;
private $currentUrl;
private $config;
/**
* 上传二进制流到七牛
*
* @param $upToken 上传凭证
* @param $key 上传文件名
* @param $inputStream 上传二进制流
* @param $size 上传流的大小
* @param $params 自定义变量
* @param $mime 上传数据的mimeType
*
* @link http://developer.qiniu.com/docs/v6/api/overview/up/response/vars.html#xvar
*/
public function __construct(
$upToken,
$key,
$inputStream,
$size,
$params,
$mime,
$config
) {
$this->upToken = $upToken;
$this->key = $key;
$this->inputStream = $inputStream;
$this->size = $size;
$this->params = $params;
$this->mime = $mime;
$this->contexts = array();
$this->config = $config;
list($accessKey, $bucket, $err) = \Qiniu\explodeUpToken($upToken);
if ($err != null) {
return array(null, $err);
}
$upHost = $config->getUpHost($accessKey, $bucket);
if ($err != null) {
throw new \Exception($err->message(), 1);
}
$this->host = $upHost;
}
/**
* 上传操作
*/
public function upload($fname)
{
$uploaded = 0;
while ($uploaded < $this->size) {
$blockSize = $this->blockSize($uploaded);
$data = fread($this->inputStream, $blockSize);
if ($data === false) {
throw new \Exception("file read failed", 1);
}
$crc = \Qiniu\crc32_data($data);
$response = $this->makeBlock($data, $blockSize);
$ret = null;
if ($response->ok() && $response->json() != null) {
$ret = $response->json();
}
if ($response->statusCode < 0) {
list($accessKey, $bucket, $err) = \Qiniu\explodeUpToken($this->upToken);
if ($err != null) {
return array(null, $err);
}
$upHostBackup = $this->config->getUpBackupHost($accessKey, $bucket);
$this->host = $upHostBackup;
}
if ($response->needRetry() || !isset($ret['crc32']) || $crc != $ret['crc32']) {
$response = $this->makeBlock($data, $blockSize);
$ret = $response->json();
}
if (!$response->ok() || !isset($ret['crc32']) || $crc != $ret['crc32']) {
return array(null, new Error($this->currentUrl, $response));
}
array_push($this->contexts, $ret['ctx']);
$uploaded += $blockSize;
}
return $this->makeFile($fname);
}
/**
* 创建块
*/
private function makeBlock($block, $blockSize)
{
$url = $this->host . '/mkblk/' . $blockSize;
return $this->post($url, $block);
}
private function fileUrl($fname)
{
$url = $this->host . '/mkfile/' . $this->size;
$url .= '/mimeType/' . \Qiniu\base64_urlSafeEncode($this->mime);
if ($this->key != null) {
$url .= '/key/' . \Qiniu\base64_urlSafeEncode($this->key);
}
$url .= '/fname/' . \Qiniu\base64_urlSafeEncode($fname);
if (!empty($this->params)) {
foreach ($this->params as $key => $value) {
$val = \Qiniu\base64_urlSafeEncode($value);
$url .= "/$key/$val";
}
}
return $url;
}
/**
* 创建文件
*/
private function makeFile($fname)
{
$url = $this->fileUrl($fname);
$body = implode(',', $this->contexts);
$response = $this->post($url, $body);
if ($response->needRetry()) {
$response = $this->post($url, $body);
}
if (!$response->ok()) {
return array(null, new Error($this->currentUrl, $response));
}
return array($response->json(), null);
}
private function post($url, $data)
{
$this->currentUrl = $url;
$headers = array('Authorization' => 'UpToken ' . $this->upToken);
return Client::post($url, $data, $headers);
}
private function blockSize($uploaded)
{
if ($this->size < $uploaded + Config::BLOCK_SIZE) {
return $this->size - $uploaded;
}
return Config::BLOCK_SIZE;
}
}

View File

@@ -0,0 +1,144 @@
<?php
namespace Qiniu\Storage;
use Qiniu\Config;
use Qiniu\Http\HttpClient;
use Qiniu\Storage\ResumeUploader;
use Qiniu\Storage\FormUploader;
/**
* 主要涉及了资源上传接口的实现
*
* @link http://developer.qiniu.com/docs/v6/api/reference/up/
*/
final class UploadManager
{
private $config;
public function __construct(Config $config = null)
{
if ($config === null) {
$config = new Config();
}
$this->config = $config;
}
/**
* 上传二进制流到七牛
*
* @param $upToken 上传凭证
* @param $key 上传文件名
* @param $data 上传二进制流
* @param $params 自定义变量,规格参考
* http://developer.qiniu.com/docs/v6/api/overview/up/response/vars.html#xvar
* @param $mime 上传数据的mimeType
* @param $checkCrc 是否校验crc32
*
* @return array 包含已上传文件的信息,类似:
* [
* "hash" => "<Hash string>",
* "key" => "<Key string>"
* ]
*/
public function put(
$upToken,
$key,
$data,
$params = null,
$mime = 'application/octet-stream',
$fname = null
) {
$params = self::trimParams($params);
return FormUploader::put(
$upToken,
$key,
$data,
$this->config,
$params,
$mime,
$fname
);
}
/**
* 上传文件到七牛
*
* @param $upToken 上传凭证
* @param $key 上传文件名
* @param $filePath 上传文件的路径
* @param $params 自定义变量,规格参考
* http://developer.qiniu.com/docs/v6/api/overview/up/response/vars.html#xvar
* @param $mime 上传数据的mimeType
* @param $checkCrc 是否校验crc32
*
* @return array 包含已上传文件的信息,类似:
* [
* "hash" => "<Hash string>",
* "key" => "<Key string>"
* ]
*/
public function putFile(
$upToken,
$key,
$filePath,
$params = null,
$mime = 'application/octet-stream',
$checkCrc = false
) {
$file = fopen($filePath, 'rb');
if ($file === false) {
throw new \Exception("file can not open", 1);
}
$params = self::trimParams($params);
$stat = fstat($file);
$size = $stat['size'];
if ($size <= Config::BLOCK_SIZE) {
$data = fread($file, $size);
fclose($file);
if ($data === false) {
throw new \Exception("file can not read", 1);
}
return FormUploader::put(
$upToken,
$key,
$data,
$this->config,
$params,
$mime,
basename($filePath)
);
}
$up = new ResumeUploader(
$upToken,
$key,
$file,
$size,
$params,
$mime,
$this->config
);
$ret = $up->upload(basename($filePath));
fclose($file);
return $ret;
}
public static function trimParams($params)
{
if ($params === null) {
return null;
}
$ret = array();
foreach ($params as $k => $v) {
$pos1 = strpos($k, 'x:');
$pos2 = strpos($k, 'x-qn-meta-');
if (($pos1 === 0 || $pos2 === 0) && !empty($v)) {
$ret[$k] = $v;
}
}
return $ret;
}
}

View File

@@ -0,0 +1,197 @@
<?php
namespace Qiniu;
use Qiniu\Http\Client;
use Qiniu\Http\Error;
final class Zone
{
//源站上传域名
public $srcUpHosts;
//CDN加速上传域名
public $cdnUpHosts;
//资源管理域名
public $rsHost;
//资源列举域名
public $rsfHost;
//资源处理域名
public $apiHost;
//IOVIP域名
public $iovipHost;
//构造一个Zone对象
public function __construct(
$srcUpHosts = array(),
$cdnUpHosts = array(),
$rsHost = "rs.qiniu.com",
$rsfHost = "rsf.qiniu.com",
$apiHost = "api.qiniu.com",
$iovipHost = null
) {
$this->srcUpHosts = $srcUpHosts;
$this->cdnUpHosts = $cdnUpHosts;
$this->rsHost = $rsHost;
$this->rsfHost = $rsfHost;
$this->apiHost = $apiHost;
$this->iovipHost = $iovipHost;
}
//华东机房
public static function zone0()
{
$Zone_z0 = new Zone(
array("up.qiniup.com", 'up-jjh.qiniup.com', 'up-xs.qiniup.com'),
array('upload.qiniup.com', 'upload-jjh.qiniup.com', 'upload-xs.qiniup.com'),
'rs.qbox.me',
'rsf.qbox.me',
'api.qiniu.com',
'iovip.qbox.me'
);
return $Zone_z0;
}
//华东机房内网上传
public static function zoneZ0()
{
$Zone_z01 = new Zone(
array("free-qvm-z0-xs.qiniup.com"),
'rs.qbox.me',
'rsf.qbox.me',
'api.qiniu.com',
'iovip.qbox.me'
);
return $Zone_z01;
}
//华北机房内网上传
public static function zoneZ1()
{
$Zone_z12 = new Zone(
array("free-qvm-z1-zz.qiniup.com"),
"rs-z1.qbox.me",
"rsf-z1.qbox.me",
"api-z1.qiniu.com",
"iovip-z1.qbox.me"
);
return $Zone_z12;
}
//华北机房
public static function zone1()
{
$Zone_z1 = new Zone(
array('up-z1.qiniup.com'),
array('upload-z1.qiniup.com'),
"rs-z1.qbox.me",
"rsf-z1.qbox.me",
"api-z1.qiniu.com",
"iovip-z1.qbox.me"
);
return $Zone_z1;
}
//华南机房
public static function zone2()
{
$Zone_z2 = new Zone(
array('up-z2.qiniup.com', 'up-dg.qiniup.com', 'up-fs.qiniup.com'),
array('upload-z2.qiniup.com', 'upload-dg.qiniup.com', 'upload-fs.qiniup.com'),
"rs-z2.qbox.me",
"rsf-z2.qbox.me",
"api-z2.qiniu.com",
"iovip-z2.qbox.me"
);
return $Zone_z2;
}
//北美机房
public static function zoneNa0()
{
//北美机房
$Zone_na0 = new Zone(
array('up-na0.qiniup.com'),
array('upload-na0.qiniup.com'),
"rs-na0.qbox.me",
"rsf-na0.qbox.me",
"api-na0.qiniu.com",
"iovip-na0.qbox.me"
);
return $Zone_na0;
}
//新加坡机房
public static function zoneAs0()
{
//新加坡机房
$Zone_as0 = new Zone(
array('up-as0.qiniup.com'),
array('upload-as0.qiniup.com'),
"rs-as0.qbox.me",
"rsf-as0.qbox.me",
"api-as0.qiniu.com",
"iovip-as0.qbox.me"
);
return $Zone_as0;
}
/*
* GET /v2/query?ak=<ak>&&bucket=<bucket>
**/
public static function queryZone($ak, $bucket)
{
$zone = new Zone();
$url = Config::UC_HOST . '/v2/query' . "?ak=$ak&bucket=$bucket";
$ret = Client::Get($url);
if (!$ret->ok()) {
return array(null, new Error($url, $ret));
}
$r = ($ret->body === null) ? array() : $ret->json();
//print_r($ret);
//parse zone;
$iovipHost = $r['io']['src']['main'][0];
$zone->iovipHost = $iovipHost;
$accMain = $r['up']['acc']['main'][0];
array_push($zone->cdnUpHosts, $accMain);
if (isset($r['up']['acc']['backup'])) {
foreach ($r['up']['acc']['backup'] as $key => $value) {
array_push($zone->cdnUpHosts, $value);
}
}
$srcMain = $r['up']['src']['main'][0];
array_push($zone->srcUpHosts, $srcMain);
if (isset($r['up']['src']['backup'])) {
foreach ($r['up']['src']['backup'] as $key => $value) {
array_push($zone->srcUpHosts, $value);
}
}
//set specific hosts
if (strstr($zone->iovipHost, "z1") !== false) {
$zone->rsHost = "rs-z1.qbox.me";
$zone->rsfHost = "rsf-z1.qbox.me";
$zone->apiHost = "api-z1.qiniu.com";
} elseif (strstr($zone->iovipHost, "z2") !== false) {
$zone->rsHost = "rs-z2.qbox.me";
$zone->rsfHost = "rsf-z2.qbox.me";
$zone->apiHost = "api-z2.qiniu.com";
} elseif (strstr($zone->iovipHost, "na0") !== false) {
$zone->rsHost = "rs-na0.qbox.me";
$zone->rsfHost = "rsf-na0.qbox.me";
$zone->apiHost = "api-na0.qiniu.com";
} elseif (strstr($zone->iovipHost, "as0") !== false) {
$zone->rsHost = "rs-as0.qbox.me";
$zone->rsfHost = "rsf-as0.qbox.me";
$zone->apiHost = "api-as0.qiniu.com";
} else {
$zone->rsHost = "rs.qbox.me";
$zone->rsfHost = "rsf.qbox.me";
$zone->apiHost = "api.qiniu.com";
}
return $zone;
}
}

View File

@@ -0,0 +1,264 @@
<?php
namespace Qiniu;
use Qiniu\Config;
if (!defined('QINIU_FUNCTIONS_VERSION')) {
define('QINIU_FUNCTIONS_VERSION', Config::SDK_VER);
/**
* 计算文件的crc32检验码:
*
* @param $file string 待计算校验码的文件路径
*
* @return string 文件内容的crc32校验码
*/
function crc32_file($file)
{
$hash = hash_file('crc32b', $file);
$array = unpack('N', pack('H*', $hash));
return sprintf('%u', $array[1]);
}
/**
* 计算输入流的crc32检验码
*
* @param $data 待计算校验码的字符串
*
* @return string 输入字符串的crc32校验码
*/
function crc32_data($data)
{
$hash = hash('crc32b', $data);
$array = unpack('N', pack('H*', $hash));
return sprintf('%u', $array[1]);
}
/**
* 对提供的数据进行urlsafe的base64编码。
*
* @param string $data 待编码的数据,一般为字符串
*
* @return string 编码后的字符串
* @link http://developer.qiniu.com/docs/v6/api/overview/appendix.html#urlsafe-base64
*/
function base64_urlSafeEncode($data)
{
$find = array('+', '/');
$replace = array('-', '_');
return str_replace($find, $replace, base64_encode($data));
}
/**
* 对提供的urlsafe的base64编码的数据进行解码
*
* @param string $str 待解码的数据,一般为字符串
*
* @return string 解码后的字符串
*/
function base64_urlSafeDecode($str)
{
$find = array('-', '_');
$replace = array('+', '/');
return base64_decode(str_replace($find, $replace, $str));
}
/**
* Wrapper for JSON decode that implements error detection with helpful
* error messages.
*
* @param string $json JSON data to parse
* @param bool $assoc When true, returned objects will be converted
* into associative arrays.
* @param int $depth User specified recursion depth.
*
* @return mixed
* @throws \InvalidArgumentException if the JSON cannot be parsed.
* @link http://www.php.net/manual/en/function.json-decode.php
*/
function json_decode($json, $assoc = false, $depth = 512)
{
static $jsonErrors = array(
JSON_ERROR_DEPTH => 'JSON_ERROR_DEPTH - Maximum stack depth exceeded',
JSON_ERROR_STATE_MISMATCH => 'JSON_ERROR_STATE_MISMATCH - Underflow or the modes mismatch',
JSON_ERROR_CTRL_CHAR => 'JSON_ERROR_CTRL_CHAR - Unexpected control character found',
JSON_ERROR_SYNTAX => 'JSON_ERROR_SYNTAX - Syntax error, malformed JSON',
JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8 - Malformed UTF-8 characters, possibly incorrectly encoded'
);
if (empty($json)) {
return null;
}
$data = \json_decode($json, $assoc, $depth);
if (JSON_ERROR_NONE !== json_last_error()) {
$last = json_last_error();
throw new \InvalidArgumentException(
'Unable to parse JSON data: '
. (isset($jsonErrors[$last])
? $jsonErrors[$last]
: 'Unknown error')
);
}
return $data;
}
/**
* 计算七牛API中的数据格式
*
* @param $bucket 待操作的空间名
* @param $key 待操作的文件名
*
* @return string 符合七牛API规格的数据格式
* @link http://developer.qiniu.com/docs/v6/api/reference/data-formats.html
*/
function entry($bucket, $key)
{
$en = $bucket;
if (!empty($key)) {
$en = $bucket . ':' . $key;
}
return base64_urlSafeEncode($en);
}
/**
* array 辅助方法无值时不set
*
* @param $array 待操作array
* @param $key key
* @param $value value 为null时 不设置
*
* @return array 原来的array便于连续操作
*/
function setWithoutEmpty(&$array, $key, $value)
{
if (!empty($value)) {
$array[$key] = $value;
}
return $array;
}
/**
* 缩略图链接拼接
*
* @param string $url 图片链接
* @param int $mode 缩略模式
* @param int $width 宽度
* @param int $height 长度
* @param string $format 输出类型
* @param int $quality 图片质量
* @param int $interlace 是否支持渐进显示
* @param int $ignoreError 忽略结果
* @return string
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/imageview2.html
* @author Sherlock Ren <sherlock_ren@icloud.com>
*/
function thumbnail(
$url,
$mode,
$width,
$height,
$format = null,
$quality = null,
$interlace = null,
$ignoreError = 1
) {
static $imageUrlBuilder = null;
if (is_null($imageUrlBuilder)) {
$imageUrlBuilder = new \Qiniu\Processing\ImageUrlBuilder;
}
return call_user_func_array(array($imageUrlBuilder, 'thumbnail'), func_get_args());
}
/**
* 图片水印
*
* @param string $url 图片链接
* @param string $image 水印图片链接
* @param numeric $dissolve 透明度
* @param string $gravity 水印位置
* @param numeric $dx 横轴边距
* @param numeric $dy 纵轴边距
* @param numeric $watermarkScale 自适应原图的短边比例
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html
* @return string
* @author Sherlock Ren <sherlock_ren@icloud.com>
*/
function waterImg(
$url,
$image,
$dissolve = 100,
$gravity = 'SouthEast',
$dx = null,
$dy = null,
$watermarkScale = null
) {
static $imageUrlBuilder = null;
if (is_null($imageUrlBuilder)) {
$imageUrlBuilder = new \Qiniu\Processing\ImageUrlBuilder;
}
return call_user_func_array(array($imageUrlBuilder, 'waterImg'), func_get_args());
}
/**
* 文字水印
*
* @param string $url 图片链接
* @param string $text 文字
* @param string $font 文字字体
* @param string $fontSize 文字字号
* @param string $fontColor 文字颜色
* @param numeric $dissolve 透明度
* @param string $gravity 水印位置
* @param numeric $dx 横轴边距
* @param numeric $dy 纵轴边距
* @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html#text-watermark
* @return string
* @author Sherlock Ren <sherlock_ren@icloud.com>
*/
function waterText(
$url,
$text,
$font = '黑体',
$fontSize = 0,
$fontColor = null,
$dissolve = 100,
$gravity = 'SouthEast',
$dx = null,
$dy = null
) {
static $imageUrlBuilder = null;
if (is_null($imageUrlBuilder)) {
$imageUrlBuilder = new \Qiniu\Processing\ImageUrlBuilder;
}
return call_user_func_array(array($imageUrlBuilder, 'waterText'), func_get_args());
}
/**
* 从uptoken解析accessKey和bucket
*
* @param $upToken
* @return array(ak,bucket,err=null)
*/
function explodeUpToken($upToken)
{
$items = explode(':', $upToken);
if (count($items) != 3) {
return array(null, null, "invalid uptoken");
}
$accessKey = $items[0];
$putPolicy = json_decode(base64_urlSafeDecode($items[2]));
$scope = $putPolicy->scope;
$scopeItems = explode(':', $scope);
$bucket = $scopeItems[0];
return array($accessKey, $bucket, null);
}
}

View File

@@ -0,0 +1,4 @@
export QINIU_ACCESS_KEY=xxx
export QINIU_SECRET_KEY=xxx
export QINIU_TEST_BUCKET=phpsdk
export QINIU_TEST_DOMAIN=phpsdk.qiniudn.com

View File

@@ -0,0 +1,71 @@
<?php
// Hack to override the time returned from the S3SignatureV4
// @codingStandardsIgnoreStart
namespace Qiniu {
function time()
{
return isset($_SERVER['override_qiniu_auth_time'])
? 1234567890
: \time();
}
}
namespace Qiniu\Tests {
use Qiniu\Auth;
// @codingStandardsIgnoreEnd
class AuthTest extends \PHPUnit_Framework_TestCase
{
public function testSign()
{
global $dummyAuth;
$token = $dummyAuth->sign('test');
$this->assertEquals('abcdefghklmnopq:mSNBTR7uS2crJsyFr2Amwv1LaYg=', $token);
}
public function testSignWithData()
{
global $dummyAuth;
$token = $dummyAuth->signWithData('test');
$this->assertEquals('abcdefghklmnopq:-jP8eEV9v48MkYiBGs81aDxl60E=:dGVzdA==', $token);
}
public function testSignRequest()
{
global $dummyAuth;
$token = $dummyAuth->signRequest('http://www.qiniu.com?go=1', 'test', '');
$this->assertEquals('abcdefghklmnopq:cFyRVoWrE3IugPIMP5YJFTO-O-Y=', $token);
$ctype = 'application/x-www-form-urlencoded';
$token = $dummyAuth->signRequest('http://www.qiniu.com?go=1', 'test', $ctype);
$this->assertEquals($token, 'abcdefghklmnopq:svWRNcacOE-YMsc70nuIYdaa1e4=');
}
public function testPrivateDownloadUrl()
{
global $dummyAuth;
$_SERVER['override_qiniu_auth_time'] = true;
$url = $dummyAuth->privateDownloadUrl('http://www.qiniu.com?go=1');
$expect = 'http://www.qiniu.com?go=1&e=1234571490&token=abcdefghklmnopq:8vzBeLZ9W3E4kbBLFLW0Xe0u7v4=';
$this->assertEquals($expect, $url);
unset($_SERVER['override_qiniu_auth_time']);
}
public function testUploadToken()
{
global $dummyAuth;
$_SERVER['override_qiniu_auth_time'] = true;
$token = $dummyAuth->uploadToken('1', '2', 3600, array('endUser' => 'y'));
// @codingStandardsIgnoreStart
$exp = 'abcdefghklmnopq:yyeexeUkPOROoTGvwBjJ0F0VLEo=:eyJlbmRVc2VyIjoieSIsInNjb3BlIjoiMToyIiwiZGVhZGxpbmUiOjEyMzQ1NzE0OTB9';
// @codingStandardsIgnoreEnd
$this->assertEquals($exp, $token);
unset($_SERVER['override_qiniu_auth_time']);
}
public function testVerifyCallback()
{
}
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Qiniu\Tests;
use Qiniu;
class Base64Test extends \PHPUnit_Framework_TestCase
{
public function testUrlSafe()
{
$a = '你好';
$b = \Qiniu\base64_urlSafeEncode($a);
$this->assertEquals($a, \Qiniu\base64_urlSafeDecode($b));
}
}

View File

@@ -0,0 +1,227 @@
<?php
namespace Qiniu\Tests;
use Qiniu\Storage\BucketManager;
class BucketTest extends \PHPUnit_Framework_TestCase
{
protected $bucketManager;
protected $dummyBucketManager;
protected $bucketName;
protected $key;
protected $key2;
protected function setUp()
{
global $bucketName;
global $key;
global $key2;
$this->bucketName = $bucketName;
$this->key = $key;
$this->key2 = $key2;
global $testAuth;
$this->bucketManager = new BucketManager($testAuth);
global $dummyAuth;
$this->dummyBucketManager = new BucketManager($dummyAuth);
}
public function testBuckets()
{
list($list, $error) = $this->bucketManager->buckets();
$this->assertTrue(in_array($this->bucketName, $list));
$this->assertNull($error);
list($list2, $error) = $this->dummyBucketManager->buckets();
$this->assertEquals(401, $error->code());
$this->assertNull($list2);
$this->assertNotNull($error->message());
}
public function testList()
{
list($ret, $error) = $this->bucketManager->listFiles($this->bucketName, null, null, 10);
$this->assertNotNull($ret['items'][0]);
$this->assertNotNull($ret['marker']);
}
public function testStat()
{
list($stat, $error) = $this->bucketManager->stat($this->bucketName, $this->key);
$this->assertNotNull($stat);
$this->assertNull($error);
$this->assertNotNull($stat['hash']);
list($stat, $error) = $this->bucketManager->stat($this->bucketName, 'nofile');
$this->assertNull($stat);
$this->assertEquals(612, $error->code());
$this->assertNotNull($error->message());
list($stat, $error) = $this->bucketManager->stat('nobucket', 'nofile');
$this->assertNull($stat);
$this->assertEquals(631, $error->code());
$this->assertNotNull($error->message());
}
public function testDelete()
{
$error = $this->bucketManager->delete($this->bucketName, 'del');
$this->assertEquals(612, $error->code());
}
public function testRename()
{
$key = 'renamefrom' . rand();
$this->bucketManager->copy($this->bucketName, $this->key, $this->bucketName, $key);
$key2 = 'renameto' . $key;
$error = $this->bucketManager->rename($this->bucketName, $key, $key2);
$this->assertNull($error);
$error = $this->bucketManager->delete($this->bucketName, $key2);
$this->assertNull($error);
}
public function testCopy()
{
$key = 'copyto' . rand();
$this->bucketManager->delete($this->bucketName, $key);
$error = $this->bucketManager->copy(
$this->bucketName,
$this->key,
$this->bucketName,
$key
);
$this->assertNull($error);
//test force copy
$error = $this->bucketManager->copy(
$this->bucketName,
$this->key2,
$this->bucketName,
$key,
true
);
$this->assertNull($error);
list($key2Stat,) = $this->bucketManager->stat($this->bucketName, $this->key2);
list($key2CopiedStat,) = $this->bucketManager->stat($this->bucketName, $key);
$this->assertEquals($key2Stat['hash'], $key2CopiedStat['hash']);
$error = $this->bucketManager->delete($this->bucketName, $key);
$this->assertNull($error);
}
public function testChangeMime()
{
$error = $this->bucketManager->changeMime(
$this->bucketName,
'php-sdk.html',
'text/html'
);
$this->assertNull($error);
}
public function testPrefetch()
{
$error = $this->bucketManager->prefetch(
$this->bucketName,
'php-sdk.html'
);
$this->assertNull($error);
}
public function testFetch()
{
list($ret, $error) = $this->bucketManager->fetch(
'http://developer.qiniu.com/docs/v6/sdk/php-sdk.html',
$this->bucketName,
'fetch.html'
);
$this->assertArrayHasKey('hash', $ret);
$this->assertNull($error);
list($ret, $error) = $this->bucketManager->fetch(
'http://developer.qiniu.com/docs/v6/sdk/php-sdk.html',
$this->bucketName,
''
);
$this->assertArrayHasKey('key', $ret);
$this->assertNull($error);
list($ret, $error) = $this->bucketManager->fetch(
'http://developer.qiniu.com/docs/v6/sdk/php-sdk.html',
$this->bucketName
);
$this->assertArrayHasKey('key', $ret);
$this->assertNull($error);
}
public function testBatchCopy()
{
$key = 'copyto' . rand();
$ops = BucketManager::buildBatchCopy(
$this->bucketName,
array($this->key => $key),
$this->bucketName,
true
);
list($ret, $error) = $this->bucketManager->batch($ops);
$this->assertEquals(200, $ret[0]['code']);
$ops = BucketManager::buildBatchDelete($this->bucketName, array($key));
list($ret, $error) = $this->bucketManager->batch($ops);
$this->assertEquals(200, $ret[0]['code']);
}
public function testBatchMove()
{
$key = 'movefrom' . rand();
$this->bucketManager->copy($this->bucketName, $this->key, $this->bucketName, $key);
$key2 = $key . 'to';
$ops = BucketManager::buildBatchMove(
$this->bucketName,
array($key => $key2),
$this->bucketName,
true
);
list($ret, $error) = $this->bucketManager->batch($ops);
$this->assertEquals(200, $ret[0]['code']);
$error = $this->bucketManager->delete($this->bucketName, $key2);
$this->assertNull($error);
}
public function testBatchRename()
{
$key = 'rename' . rand();
$this->bucketManager->copy($this->bucketName, $this->key, $this->bucketName, $key);
$key2 = $key . 'to';
$ops = BucketManager::buildBatchRename($this->bucketName, array($key => $key2), true);
list($ret, $error) = $this->bucketManager->batch($ops);
$this->assertEquals(200, $ret[0]['code']);
$error = $this->bucketManager->delete($this->bucketName, $key2);
$this->assertNull($error);
}
public function testBatchStat()
{
$ops = BucketManager::buildBatchStat($this->bucketName, array('php-sdk.html'));
list($ret, $error) = $this->bucketManager->batch($ops);
$this->assertEquals(200, $ret[0]['code']);
}
public function testDeleteAfterDays()
{
$key = rand();
$err = $this->bucketManager->deleteAfterDays($this->bucketName, $key, 1);
$this->assertEquals(612, $err->code());
$this->bucketManager->copy($this->bucketName, $this->key, $this->bucketName, $key);
$err = $this->bucketManager->deleteAfterDays($this->bucketName, $key, 1);
$this->assertEquals(null, $err);
}
}

View File

@@ -0,0 +1,50 @@
<?php
/**
* Created by IntelliJ IDEA.
* User: wf
* Date: 2017/6/21
* Time: AM8:46
*/
namespace Qiniu\Tests;
use Qiniu\Cdn\CdnManager;
use Qiniu\Http\Client;
class CdnManagerTest extends \PHPUnit_Framework_TestCase
{
protected $cdnManager;
protected $encryptKey;
protected $imgUrl;
protected function setUp()
{
global $timestampAntiLeechEncryptKey;
global $customDomain;
global $testAuth;
$this->cdnManager = new CdnManager($testAuth);
$this->encryptKey = $timestampAntiLeechEncryptKey;
$this->imgUrl = $customDomain . '/24.jpg';
}
public function testCreateTimestampAntiLeechUrl()
{
$signUrl = $this->cdnManager->createTimestampAntiLeechUrl($this->imgUrl, $this->encryptKey, 3600);
$response = Client::get($signUrl);
$this->assertEquals($response->statusCode, 200);
$this->assertNull($response->error);
$url2 = $this->imgUrl . '?imageInfo';
$signUrl2 = $this->cdnManager->createTimestampAntiLeechUrl($url2, $this->encryptKey, 3600);
$response = Client::get($signUrl2);
$imgInfo = $response->json();
$this->assertEquals($response->statusCode, 200);
$this->assertEquals($imgInfo['size'], 2196145);
$this->assertNull($response->error);
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace Qiniu\Tests;
use Qiniu;
class Crc32Test extends \PHPUnit_Framework_TestCase
{
public function testData()
{
$a = '你好';
$b = \Qiniu\crc32_data($a);
$this->assertEquals('1352841281', $b);
}
public function testFile()
{
$b = \Qiniu\crc32_file(__file__);
$c = \Qiniu\crc32_file(__file__);
$this->assertEquals($c, $b);
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Qiniu\Tests;
use Qiniu\Http\Client;
class DownloadTest extends \PHPUnit_Framework_TestCase
{
public function test()
{
global $testAuth;
$base_url = 'http://private-res.qiniudn.com/gogopher.jpg';
$private_url = $testAuth->privateDownloadUrl($base_url);
$response = Client::get($private_url);
$this->assertEquals(200, $response->statusCode);
}
public function testFop()
{
global $testAuth;
$base_url = 'http://private-res.qiniudn.com/gogopher.jpg?exif';
$private_url = $testAuth->privateDownloadUrl($base_url);
$response = Client::get($private_url);
$this->assertEquals(200, $response->statusCode);
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Qiniu\Tests;
use Qiniu\Etag;
class EtagTest extends \PHPUnit_Framework_TestCase
{
public function test0M()
{
$file = qiniuTempFile(0);
list($r, $error) = Etag::sum($file);
unlink($file);
$this->assertEquals('Fto5o-5ea0sNMlW_75VgGJCv2AcJ', $r);
$this->assertNull($error);
}
public function testLess4M()
{
$file = qiniuTempFile(3 * 1024 * 1024);
list($r, $error) = Etag::sum($file);
unlink($file);
$this->assertEquals('Fs5BpnAjRykYTg6o5E09cjuXrDkG', $r);
$this->assertNull($error);
}
public function test4M()
{
$file = qiniuTempFile(4 * 1024 * 1024);
list($r, $error) = Etag::sum($file);
unlink($file);
$this->assertEquals('FiuKULnybewpEnrfTmxjsxc-3dWp', $r);
$this->assertNull($error);
}
public function testMore4M()
{
$file = qiniuTempFile(5 * 1024 * 1024);
list($r, $error) = Etag::sum($file);
unlink($file);
$this->assertEquals('lhvyfIWMYFTq4s4alzlhXoAkqfVL', $r);
$this->assertNull($error);
}
public function test8M()
{
$file = qiniuTempFile(8 * 1024 * 1024);
list($r, $error) = Etag::sum($file);
unlink($file);
$this->assertEquals('lmRm9ZfGZ86bnMys4wRTWtJj9ClG', $r);
$this->assertNull($error);
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Qiniu\Tests;
use Qiniu\Processing\Operation;
use Qiniu\Processing\PersistentFop;
class FopTest extends \PHPUnit_Framework_TestCase
{
public function testExifPub()
{
$fop = new Operation('testres.qiniudn.com');
list($exif, $error) = $fop->execute('gogopher.jpg', 'exif');
$this->assertNull($error);
$this->assertNotNull($exif);
}
public function testExifPrivate()
{
global $testAuth;
$fop = new Operation('private-res.qiniudn.com', $testAuth);
list($exif, $error) = $fop->execute('noexif.jpg', 'exif');
$this->assertNotNull($error);
$this->assertNull($exif);
}
public function testbuildUrl()
{
$fops = 'imageView2/2/h/200';
$fop = new Operation('testres.qiniudn.com');
$url = $fop->buildUrl('gogopher.jpg', $fops);
$this->assertEquals($url, 'http://testres.qiniudn.com/gogopher.jpg?imageView2/2/h/200');
$fops = array('imageView2/2/h/200', 'imageInfo');
$url = $fop->buildUrl('gogopher.jpg', $fops);
$this->assertEquals($url, 'http://testres.qiniudn.com/gogopher.jpg?imageView2/2/h/200|imageInfo');
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Qiniu\Tests;
use Qiniu\Storage\FormUploader;
use Qiniu\Storage\UploadManager;
use Qiniu\Config;
class FormUpTest extends \PHPUnit_Framework_TestCase
{
protected $bucketName;
protected $auth;
protected $cfg;
protected function setUp()
{
global $bucketName;
$this->bucketName = $bucketName;
global $testAuth;
$this->auth = $testAuth;
$this->cfg = new Config();
}
public function testData()
{
$token = $this->auth->uploadToken($this->bucketName);
list($ret, $error) = FormUploader::put($token, 'formput', 'hello world', $this->cfg, null, 'text/plain', null);
$this->assertNull($error);
$this->assertNotNull($ret['hash']);
}
public function testData2()
{
$upManager = new UploadManager();
$token = $this->auth->uploadToken($this->bucketName);
list($ret, $error) = $upManager->put($token, 'formput', 'hello world', null, 'text/plain', null);
$this->assertNull($error);
$this->assertNotNull($ret['hash']);
}
public function testFile()
{
$key = 'formPutFile';
$token = $this->auth->uploadToken($this->bucketName, $key);
list($ret, $error) = FormUploader::putFile($token, $key, __file__, $this->cfg, null, 'text/plain', null);
$this->assertNull($error);
$this->assertNotNull($ret['hash']);
}
public function testFile2()
{
$key = 'formPutFile';
$token = $this->auth->uploadToken($this->bucketName, $key);
$upManager = new UploadManager();
list($ret, $error) = $upManager->putFile($token, $key, __file__, null, 'text/plain', null);
$this->assertNull($error);
$this->assertNotNull($ret['hash']);
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace Qiniu\Tests;
use Qiniu\Http\Client;
class HttpTest extends \PHPUnit_Framework_TestCase
{
public function testGet()
{
$response = Client::get('baidu.com');
$this->assertEquals($response->statusCode, 200);
$this->assertNotNull($response->body);
$this->assertNull($response->error);
}
public function testGetQiniu()
{
$response = Client::get('up.qiniu.com');
$this->assertEquals(405, $response->statusCode);
$this->assertNotNull($response->body);
$this->assertNotNull($response->xReqId());
$this->assertNotNull($response->xLog());
$this->assertNotNull($response->error);
}
public function testPost()
{
$response = Client::post('baidu.com', null);
$this->assertEquals($response->statusCode, 200);
$this->assertNotNull($response->body);
$this->assertNull($response->error);
}
public function testPostQiniu()
{
$response = Client::post('up.qiniu.com', null);
$this->assertEquals($response->statusCode, 400);
$this->assertNotNull($response->body);
$this->assertNotNull($response->xReqId());
$this->assertNotNull($response->xLog());
$this->assertNotNull($response->error);
}
}

View File

@@ -0,0 +1,261 @@
<?php
namespace Qiniu\Tests;
/**
* imageprocess test
*
* @package Qiniu
* @subpackage test
* @author Sherlock Ren <sherlock_ren@icloud.com>
*/
class ImageUrlBuilderTest extends \PHPUnit_Framework_TestCase
{
/**
* 缩略图测试
*
* @test
* @return void
* @author Sherlock Ren <sherlock_ren@icloud.com>
*/
public function testThumbutl()
{
$imageUrlBuilder = new \Qiniu\Processing\ImageUrlBuilder();
$url = 'http://78re52.com1.z0.glb.clouddn.com/resource/gogopher.jpg';
$url2 = $url . '?watermark/1/gravity/SouthEast/dx/0/dy/0/image/'
. 'aHR0cDovL2Fkcy1jZG4uY2h1Y2h1amllLmNvbS9Ga1R6bnpIY2RLdmRBUFc5cHZZZ3pTc21UY0tB';
// 异常测试
$this->assertEquals($url, $imageUrlBuilder->thumbnail($url, 1, 0, 0));
$this->assertEquals($url, \Qiniu\thumbnail($url, 1, 0, 0));
// 简单缩略测试
$this->assertEquals(
$url . '?imageView2/1/w/200/h/200/ignore-error/1/',
$imageUrlBuilder->thumbnail($url, 1, 200, 200)
);
$this->assertEquals(
$url . '?imageView2/1/w/200/h/200/ignore-error/1/',
\Qiniu\thumbnail($url, 1, 200, 200)
);
// 输出格式测试
$this->assertEquals(
$url . '?imageView2/1/w/200/h/200/format/png/ignore-error/1/',
$imageUrlBuilder->thumbnail($url, 1, 200, 200, 'png')
);
$this->assertEquals(
$url . '?imageView2/1/w/200/h/200/format/png/ignore-error/1/',
\Qiniu\thumbnail($url, 1, 200, 200, 'png')
);
// 渐进显示测试
$this->assertEquals(
$url . '?imageView2/1/w/200/h/200/format/png/interlace/1/ignore-error/1/',
$imageUrlBuilder->thumbnail($url, 1, 200, 200, 'png', 1)
);
$this->assertEquals(
$url . '?imageView2/1/w/200/h/200/format/png/ignore-error/1/',
\Qiniu\thumbnail($url, 1, 200, 200, 'png', 2)
);
// 图片质量测试
$this->assertEquals(
$url . '?imageView2/1/w/200/h/200/format/png/interlace/1/q/80/ignore-error/1/',
$imageUrlBuilder->thumbnail($url, 1, 200, 200, 'png', 1, 80)
);
$this->assertEquals(
$url . '?imageView2/1/w/200/h/200/format/png/interlace/1/ignore-error/1/',
\Qiniu\thumbnail($url, 1, 200, 200, 'png', 1, 101)
);
// 多参数测试
$this->assertEquals(
$url2 . '|imageView2/1/w/200/h/200/ignore-error/1/',
$imageUrlBuilder->thumbnail($url2, 1, 200, 200)
);
$this->assertEquals(
$url2 . '|imageView2/1/w/200/h/200/ignore-error/1/',
\Qiniu\thumbnail($url2, 1, 200, 200)
);
}
/**
* 图片水印测试
*
* @test
* @param void
* @return void
* @author Sherlock Ren <sherlock_ren@icloud.com>
*/
public function waterImgTest()
{
$imageUrlBuilder = new \Qiniu\Processing\ImageUrlBuilder();
$url = 'http://78re52.com1.z0.glb.clouddn.com/resource/gogopher.jpg';
$url2 = $url . '?imageView2/1/w/200/h/200/format/png/ignore-error/1/';
$image = 'http://developer.qiniu.com/resource/logo-2.jpg';
// 水印简单测试
$this->assertEquals(
$url . '?watermark/1/image/aHR0cDovL2RldmVsb3Blci5xaW5pdS5jb20vcmVzb3VyY2UvbG9nby0yLmpwZw=='
. '/dissolve/100/gravity/SouthEast/',
$imageUrlBuilder->waterImg($url, $image)
);
$this->assertEquals(
$url . '?watermark/1/image/aHR0cDovL2RldmVsb3Blci5xaW5pdS5jb20vcmVzb3VyY2UvbG9nby0yLmpwZw=='
. '/gravity/SouthEast/',
$imageUrlBuilder->waterImg($url, $image, 101)
);
$this->assertEquals(
$url . '?watermark/1/image/aHR0cDovL2RldmVsb3Blci5xaW5pdS5jb20vcmVzb3VyY2UvbG9nby0yLmpwZw==/',
$imageUrlBuilder->waterImg($url, $image, 101, 'sdfsd')
);
$this->assertEquals(
$url . '?watermark/1/image/aHR0cDovL2RldmVsb3Blci5xaW5pdS5jb20vcmVzb3VyY2UvbG9nby0yLmpwZw=='
. '/dissolve/100/gravity/SouthEast/',
\Qiniu\waterImg($url, $image)
);
// 横轴边距测试
$this->assertEquals(
$url . '?watermark/1/image/aHR0cDovL2RldmVsb3Blci5xaW5pdS5jb20vcmVzb3VyY2UvbG9nby0yLmpwZw=='
. '/dissolve/100/gravity/SouthEast/dx/10/',
$imageUrlBuilder->waterImg($url, $image, 100, 'SouthEast', 10)
);
$this->assertEquals(
$url . '?watermark/1/image/aHR0cDovL2RldmVsb3Blci5xaW5pdS5jb20vcmVzb3VyY2UvbG9nby0yLmpwZw=='
. '/dissolve/100/gravity/SouthEast/',
\Qiniu\waterImg($url, $image, 100, 'SouthEast', 'sad')
);
// 纵轴边距测试
$this->assertEquals(
$url . '?watermark/1/image/aHR0cDovL2RldmVsb3Blci5xaW5pdS5jb20vcmVzb3VyY2UvbG9nby0yLmpwZw=='
. '/dissolve/100/gravity/SouthEast/dx/10/dy/10/',
$imageUrlBuilder->waterImg($url, $image, 100, 'SouthEast', 10, 10)
);
$this->assertEquals(
$url . '?watermark/1/image/aHR0cDovL2RldmVsb3Blci5xaW5pdS5jb20vcmVzb3VyY2UvbG9nby0yLmpwZw=='
. '/dissolve/100/gravity/SouthEast/',
\Qiniu\waterImg($url, $image, 100, 'SouthEast', 'sad', 'asdf')
);
// 自适应原图的短边比例测试
$this->assertEquals(
$url . '?watermark/1/image/aHR0cDovL2RldmVsb3Blci5xaW5pdS5jb20vcmVzb3VyY2UvbG9nby0yLmpwZw=='
. '/dissolve/100/gravity/SouthEast/dx/10/dy/10/ws/0.5/',
$imageUrlBuilder->waterImg($url, $image, 100, 'SouthEast', 10, 10, 0.5)
);
$this->assertEquals(
$url . '?watermark/1/image/aHR0cDovL2RldmVsb3Blci5xaW5pdS5jb20vcmVzb3VyY2UvbG9nby0yLmpwZw=='
. '/dissolve/100/gravity/SouthEast/',
\Qiniu\waterImg($url, $image, 100, 'SouthEast', 'sad', 'asdf', 2)
);
// 多参数测试
$this->assertEquals(
$url2 . '|watermark/1/image/aHR0cDovL2RldmVsb3Blci5xaW5pdS5jb20vcmVzb3VyY2UvbG9nby0yLmpwZw=='
. '/dissolve/100/gravity/SouthEast/',
$imageUrlBuilder->waterImg($url2, $image)
);
$this->assertEquals(
$url2 . '|watermark/1/image/aHR0cDovL2RldmVsb3Blci5xaW5pdS5jb20vcmVzb3VyY2UvbG9nby0yLmpwZw=='
. '/dissolve/100/gravity/SouthEast/',
\Qiniu\waterImg($url2, $image)
);
}
/**
* 文字水印测试
*
* @test
* @param void
* @return void
* @author Sherlock Ren <sherlock_ren@icloud.com>
*/
public function waterTextTest()
{
$imageUrlBuilder = new \Qiniu\Processing\ImageUrlBuilder();
$url = 'http://78re52.com1.z0.glb.clouddn.com/resource/gogopher.jpg';
$url2 = $url . '?imageView2/1/w/200/h/200/format/png/ignore-error/1/';
$text = '测试一下';
$font = '微软雅黑';
$fontColor = '#FF0000';
// 水印简单测试
$this->assertEquals($url . '?watermark/2/text/5rWL6K-V5LiA5LiL/font/5b6u6L2v6ZuF6buR/'
. 'fontsize/500/dissolve/100/gravity/SouthEast/', $imageUrlBuilder->waterText($url, $text, $font, 500));
$this->assertEquals(
$url . '?watermark/2/text/5rWL6K-V5LiA5LiL/font/5b6u6L2v6ZuF6buR/'
. 'dissolve/100/gravity/SouthEast/',
\Qiniu\waterText($url, $text, $font, 'sdf')
);
// 字体颜色测试
$this->assertEquals(
$url . '?watermark/2/text/5rWL6K-V5LiA5LiL/font/5b6u6L2v6ZuF6buR/fontsize/500/fill/'
. 'I0ZGMDAwMA==/dissolve/100/gravity/SouthEast/',
$imageUrlBuilder->waterText($url, $text, $font, 500, $fontColor)
);
$this->assertEquals(
$url . '?watermark/2/text/5rWL6K-V5LiA5LiL/font/5b6u6L2v6ZuF6buR/fill/I0ZGMDAwMA=='
. '/dissolve/100/gravity/SouthEast/',
\Qiniu\waterText($url, $text, $font, 'sdf', $fontColor)
);
// 透明度测试
$this->assertEquals(
$url . '?watermark/2/text/5rWL6K-V5LiA5LiL/font/5b6u6L2v6ZuF6buR/fontsize/500/fill/I0ZGMDAwMA=='
. '/dissolve/80/gravity/SouthEast/',
$imageUrlBuilder->waterText($url, $text, $font, 500, $fontColor, 80)
);
$this->assertEquals(
$url . '?watermark/2/text/5rWL6K-V5LiA5LiL/font/5b6u6L2v6ZuF6buR/fill/I0ZGMDAwMA=='
. '/gravity/SouthEast/',
\Qiniu\waterText($url, $text, $font, 'sdf', $fontColor, 101)
);
// 水印位置测试
$this->assertEquals(
$url . '?watermark/2/text/5rWL6K-V5LiA5LiL/font/5b6u6L2v6ZuF6buR/fontsize/500/fill/I0ZGMDAwMA=='
. '/dissolve/80/gravity/East/',
$imageUrlBuilder->waterText($url, $text, $font, 500, $fontColor, 80, 'East')
);
$this->assertEquals(
$url . '?watermark/2/text/5rWL6K-V5LiA5LiL/font/5b6u6L2v6ZuF6buR/fill/I0ZGMDAwMA==/',
\Qiniu\waterText($url, $text, $font, 'sdf', $fontColor, 101, 'sdfsdf')
);
// 横轴距离测试
$this->assertEquals(
$url . '?watermark/2/text/5rWL6K-V5LiA5LiL/font/5b6u6L2v6ZuF6buR/fontsize/500/fill/I0ZGMDAwMA=='
. '/dissolve/80/gravity/East/dx/10/',
$imageUrlBuilder->waterText($url, $text, $font, 500, $fontColor, 80, 'East', 10)
);
$this->assertEquals(
$url . '?watermark/2/text/5rWL6K-V5LiA5LiL/font/5b6u6L2v6ZuF6buR/fill/I0ZGMDAwMA==/',
\Qiniu\waterText($url, $text, $font, 'sdf', $fontColor, 101, 'sdfsdf', 'sdfs')
);
// 纵轴距离测试
$this->assertEquals(
$url . '?watermark/2/text/5rWL6K-V5LiA5LiL/font/5b6u6L2v6ZuF6buR/fontsize/500/fill/I0ZGMDAwMA=='
. '/dissolve/80/gravity/East/dx/10/dy/10/',
$imageUrlBuilder->waterText($url, $text, $font, 500, $fontColor, 80, 'East', 10, 10)
);
$this->assertEquals(
$url . '?watermark/2/text/5rWL6K-V5LiA5LiL/font/5b6u6L2v6ZuF6buR/fill/I0ZGMDAwMA==/',
\Qiniu\waterText($url, $text, $font, 'sdf', $fontColor, 101, 'sdfsdf', 'sdfs', 'ssdf')
);
// 多参数测试
$this->assertEquals(
$url2 . '|watermark/2/text/5rWL6K-V5LiA5LiL/font/5b6u6L2v6ZuF6buR/'
. 'fontsize/500/dissolve/100/gravity/SouthEast/',
$imageUrlBuilder->waterText($url2, $text, $font, 500)
);
$this->assertEquals(
$url2 . '|watermark/2/text/5rWL6K-V5LiA5LiL/font/5b6u6L2v6ZuF6buR/'
. 'fontsize/500/dissolve/100/gravity/SouthEast/',
\Qiniu\waterText($url2, $text, $font, 500)
);
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace Qiniu\Tests;
use Qiniu\Processing\Operation;
use Qiniu\Processing\PersistentFop;
class PfopTest extends \PHPUnit_Framework_TestCase
{
public function testPfop()
{
global $testAuth;
$bucket = 'testres';
$key = 'sintel_trailer.mp4';
$pfop = new PersistentFop($testAuth, null);
$fops = 'avthumb/m3u8/segtime/10/vcodec/libx264/s/320x240';
list($id, $error) = $pfop->execute($bucket, $key, $fops);
$this->assertNull($error);
list($status, $error) = $pfop->status($id);
$this->assertNotNull($status);
$this->assertNull($error);
}
public function testPfops()
{
global $testAuth;
$bucket = 'testres';
$key = 'sintel_trailer.mp4';
$fops = array(
'avthumb/m3u8/segtime/10/vcodec/libx264/s/320x240',
'vframe/jpg/offset/7/w/480/h/360',
);
$pfop = new PersistentFop($testAuth, null);
list($id, $error) = $pfop->execute($bucket, $key, $fops);
$this->assertNull($error);
list($status, $error) = $pfop->status($id);
$this->assertNotNull($status);
$this->assertNull($error);
}
public function testMkzip()
{
global $testAuth;
$bucket = 'phpsdk';
$key = 'php-logo.png';
$pfop = new PersistentFop($testAuth, null);
$url1 = 'http://phpsdk.qiniudn.com/php-logo.png';
$url2 = 'http://phpsdk.qiniudn.com/php-sdk.html';
$zipKey = 'test.zip';
$fops = 'mkzip/2/url/' . \Qiniu\base64_urlSafeEncode($url1);
$fops .= '/url/' . \Qiniu\base64_urlSafeEncode($url2);
$fops .= '|saveas/' . \Qiniu\base64_urlSafeEncode("$bucket:$zipKey");
list($id, $error) = $pfop->execute($bucket, $key, $fops);
$this->assertNull($error);
list($status, $error) = $pfop->status($id);
$this->assertNotNull($status);
$this->assertNull($error);
}
}

View File

@@ -0,0 +1,60 @@
<?php
namespace Qiniu\Tests;
use Qiniu\Storage\ResumeUploader;
use Qiniu\Storage\UploadManager;
use Qiniu\Config;
use Qiniu\Zone;
class ResumeUpTest extends \PHPUnit_Framework_TestCase
{
protected $bucketName;
protected $auth;
protected function setUp()
{
global $bucketName;
$this->bucketName = $bucketName;
global $testAuth;
$this->auth = $testAuth;
}
public function test4ML()
{
$key = 'resumePutFile4ML';
$upManager = new UploadManager();
$token = $this->auth->uploadToken($this->bucketName, $key);
$tempFile = qiniuTempFile(4 * 1024 * 1024 + 10);
list($ret, $error) = $upManager->putFile($token, $key, $tempFile);
$this->assertNull($error);
$this->assertNotNull($ret['hash']);
unlink($tempFile);
}
public function test4ML2()
{
$key = 'resumePutFile4ML';
$zone = new Zone(array('up.qiniup.com'));
$cfg = new Config($zone);
$upManager = new UploadManager($cfg);
$token = $this->auth->uploadToken($this->bucketName, $key);
$tempFile = qiniuTempFile(4 * 1024 * 1024 + 10);
list($ret, $error) = $upManager->putFile($token, $key, $tempFile);
$this->assertNull($error);
$this->assertNotNull($ret['hash']);
unlink($tempFile);
}
// public function test8M()
// {
// $key = 'resumePutFile8M';
// $upManager = new UploadManager();
// $token = $this->auth->uploadToken($this->bucketName, $key);
// $tempFile = qiniuTempFile(8*1024*1024+10);
// list($ret, $error) = $upManager->putFile($token, $key, $tempFile);
// $this->assertNull($error);
// $this->assertNotNull($ret['hash']);
// unlink($tempFile);
// }
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Qiniu\Tests;
use Qiniu;
use Qiniu\Zone;
class ZoneTest extends \PHPUnit_Framework_TestCase
{
protected $zone;
protected $zoneHttps;
protected $ak;
protected $bucketName;
protected $bucketNameBC;
protected $bucketNameNA;
protected function setUp()
{
global $bucketName;
$this->bucketName = $bucketName;
global $bucketNameBC;
$this->bucketNameBC = $bucketNameBC;
global $bucketNameNA;
$this->bucketNameNA = $bucketNameNA;
global $accessKey;
$this->ak = $accessKey;
$this->zone = new Zone();
$this->zoneHttps = new Zone('https');
}
public function testUpHosts()
{
$zone = Zone::queryZone($this->ak, $this->bucketName);
$this->assertContains('upload.qiniup.com', $zone->cdnUpHosts);
$zone = Zone::queryZone($this->ak, $this->bucketNameBC);
$this->assertContains('upload-z1.qiniup.com', $zone->cdnUpHosts);
$zone = Zone::queryZone($this->ak, $this->bucketNameNA);
$this->assertContains('upload-na0.qiniup.com', $zone->cdnUpHosts);
}
public function testIoHosts()
{
$zone = Zone::queryZone($this->ak, $this->bucketName);
$this->assertEquals($zone->iovipHost, 'iovip.qbox.me');
$zone = Zone::queryZone($this->ak, $this->bucketNameBC);
$this->assertEquals($zone->iovipHost, 'iovip-z1.qbox.me');
$zone = Zone::queryZone($this->ak, $this->bucketNameNA);
$this->assertEquals($zone->iovipHost, 'iovip-na0.qbox.me');
}
}

View File

@@ -0,0 +1,43 @@
<?php
// @codingStandardsIgnoreFile
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
$accessKey = getenv('QINIU_ACCESS_KEY');
$secretKey = getenv('QINIU_SECRET_KEY');
$testAuth = new Auth($accessKey, $secretKey);
$bucketName = 'phpsdk';
$key = 'php-logo.png';
$key2 = 'niu.jpg';
$bucketNameBC = 'phpsdk-bc';
$bucketNameNA = 'phpsdk-na';
$dummyAccessKey = 'abcdefghklmnopq';
$dummySecretKey = '1234567890';
$dummyAuth = new Auth($dummyAccessKey, $dummySecretKey);
//cdn
$timestampAntiLeechEncryptKey = getenv('QINIU_TIMESTAMP_ENCRPTKEY');
$customDomain = "http://phpsdk.qiniuts.com";
$tid = getenv('TRAVIS_JOB_NUMBER');
if (!empty($tid)) {
$pid = getmypid();
$tid = strstr($tid, '.');
$tid .= '.' . $pid;
}
function qiniuTempFile($size)
{
$fileName = tempnam(sys_get_temp_dir(), 'qiniu_');
$file = fopen($fileName, 'wb');
if ($size > 0) {
fseek($file, $size - 1);
fwrite($file, ' ');
}
fclose($file);
return $fileName;
}