PageRenderTime 61ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/platform/sae.class.php

https://github.com/ueffort/fn-php
PHP | 579 lines | 461 code | 10 blank | 108 comment | 47 complexity | a6381434667b772f2604c2631756feb3 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. <?php
  2. //新浪云平台,云平台环境Paas,用以扩展服务接口
  3. class FN_platform_sae extends FN_platform{
  4. private $accesskey = null;
  5. private $securekey = null;
  6. private $appid = null;
  7. protected $PlatformSelf = 'sae';
  8. public function __construct($config){
  9. if($this->isCloudSelf()){
  10. $this->accesskey = getenv('HTTP_BAE_ENV_AK');
  11. $this->securekey = getenv('HTTP_BAE_ENV_SK');
  12. $this->appid = getenv('HTTP_BAE_ENV_APPID');
  13. }else{
  14. $this->accesskey = $config['accesskey'];
  15. $this->securekey = $config['securekey'];
  16. }
  17. }
  18. //统一调用云平台服务
  19. /**
  20. * 获取基础服务
  21. * @param string $servername 调用的服务名称
  22. * @param string $config 映射名称,默认为default
  23. * @return class
  24. */
  25. public function server($servername,&$config){
  26. switch($servername){
  27. case 'cache':
  28. //http://developer.baidu.com/wiki/index.php?title=docs/cplat/rt/php/cache
  29. if(!$this->isCloudSelf()) return false;
  30. require_once ('BaeMemcache.class.php');
  31. return new BaeMemcache();
  32. case 'count':
  33. //http://developer.baidu.com/wiki/index.php?title=docs/cplat/rt/php/counter
  34. if(!$this->isCloudSelf()) return false;
  35. require_once ('BaeCounter.class.php');
  36. return new BaeCounter();
  37. case 'rank':
  38. //http://developer.baidu.com/wiki/index.php?title=docs/cplat/rt/php/rank
  39. if(!$this->isCloudSelf()) return false;
  40. require_once ('BaeRankManager.class.php');
  41. return BaeRankManager::getInstance();
  42. case 'database':
  43. if(!$this->isCloudSelf()) return false;
  44. switch($config['drive']){
  45. case 'mysql':
  46. //http://developer.baidu.com/wiki/index.php?title=docs/cplat/rt/php/mysql
  47. $config['host'] = getenv('HTTP_BAE_ENV_ADDR_SQL_IP');
  48. $config['port'] = getenv('HTTP_BAE_ENV_ADDR_SQL_PORT');
  49. $config['user'] = $this->accesskey;
  50. $config['pass'] = $this->securekey;
  51. break;
  52. case 'mongodb':
  53. //http://developer.baidu.com/wiki/index.php?title=docs/cplat/rt/php/mongodb
  54. $config['host'] = getenv('HTTP_BAE_ENV_ADDR_MONGO_IP');
  55. $config['port'] = getenv('HTTP_BAE_ENV_ADDR_MONGO_PORT');
  56. $config['user'] = $this->accesskey;
  57. $config['pass'] = $this->securekey;
  58. break;
  59. case 'redis':
  60. //http://developer.baidu.com/wiki/index.php?title=docs/cplat/rt/php/redis
  61. $config['host'] = getenv('HTTP_BAE_ENV_ADDR_REDIS_IP');
  62. $config['port'] = getenv('HTTP_BAE_ENV_ADDR_REDIS_PORT');
  63. $config['pass'] = $this->accesskey . '-' . $this->securekey . '' . $config['dbname'];
  64. break;
  65. }
  66. break;
  67. case 'template':
  68. if(!$this->isCloudSelf()) return false;
  69. switch($config['drive']){
  70. case 'smarty':
  71. $config['compile_dir'] = '%template/';
  72. $config['cache_dir'] = '%cache/';
  73. unset($config['platform']);
  74. break;
  75. }
  76. break;
  77. case 'log':
  78. //http://developer.baidu.com/wiki/index.php?title=docs/cplat/rt/php/log
  79. if(!$this->isCloudSelf()) return false;
  80. require_once ('BaeLog.class.php');
  81. /*
  82. //打印一条警告日志,包括日志级别和日志内容
  83. $logger ->logWrite(2, "this is for warning log print ");
  84. //打印一条轨迹日志
  85. $logger ->logTrace("this is for trace log print ");
  86. //打印一条通知日志
  87. $logger ->logNotice("this is for notice log print ");
  88. //打印一条调试日志
  89. $logger ->logDebug("this is for debug log print ");
  90. //打印一条警告日志
  91. $logger ->logWarning("this is for warning log print ");
  92. //打印一条致命日志
  93. $logger ->logFatal("this is for fatal log print ");
  94. */
  95. return BaeLog::getInstance();
  96. case 'image':
  97. //http://developer.baidu.com/wiki/index.php?title=docs/cplat/rt/php/image
  98. if(!$this->isCloudSelf()) return false;
  99. require_once ('BaeImageService.class.php');
  100. return new FN_platform_baeimage();
  101. case 'vcode'://是image服务中的一款,但操作方式所以独立出来
  102. //http://developer.baidu.com/wiki/index.php?title=docs/cplat/rt/php/image#.E9.AA.8C.E8.AF.81.E7.A0.81.E5.8A.9F.E8.83.BD.EF.BC.88.E5.8F.AA.E6.94.AF.E6.8C.81.E5.8F.82.E6.95.B0.E6.95.B0.E7.BB.84.E6.96.B9.E5.BC.8F.EF.BC.89
  103. if(!$this->isCloudSelf()) return false;
  104. require_once ('BaeImageService.class.php');
  105. return new FN_platform_baeVCode();
  106. case 'taskqueue'://异步操作,一对一
  107. //http://developer.baidu.com/wiki/index.php?title=docs/cplat/rt/php/taskqueue
  108. if(!$this->isCloudSelf()) return false;
  109. require_once ('BaeTaskQueueManager.class.php');
  110. return BaeTaskQueueManager::getInstance();
  111. case 'storage'://BCS云存储
  112. //http://developer.baidu.com/wiki/index.php?title=docs/cplat/stor/api
  113. $config['accesskey'] = $this->accesskey;
  114. $config['securekey'] = $this->securekey;
  115. return new FN_platform_baeStorage($config);
  116. case 'queue'://云消息,异步操作,多对多
  117. //http://developer.baidu.com/wiki/index.php?title=docs/cplat/mq/api
  118. $config['accesskey'] = $this->accesskey;
  119. $config['securekey'] = $this->securekey;
  120. return new FN_platform_baeQueue($config);
  121. case 'mail':
  122. //http://developer.baidu.com/wiki/index.php?title=docs/cplat/mq/api#mail
  123. $config['accesskey'] = $this->accesskey;
  124. $config['securekey'] = $this->securekey;
  125. return new FN_platform_baeMail($config);
  126. case 'channel'://云推送
  127. //http://developer.baidu.com/wiki/index.php?title=docs/cplat/push/api
  128. $config['accesskey'] = $this->accesskey;
  129. $config['securekey'] = $this->securekey;
  130. return new FN_platform_baeChannel($config);
  131. case 'map'://LBS地图
  132. //http://lbsyun.baidu.com/
  133. return false;
  134. }
  135. }
  136. public function parsePath($dir,$Symbol){
  137. switch($Symbol){
  138. case '%':
  139. return sys_get_temp_dir().'/'.substr($dir,1);//缓存目录
  140. default:
  141. default:return $dir;
  142. }
  143. }
  144. }
  145. class FN_platform_baeimage{
  146. private $image = null;
  147. private $type = null;
  148. private $Service = null;
  149. public function __construct(){
  150. $this->Service = new BaeImageService();
  151. }
  152. public function __call($fname,$argus){
  153. call_user_func_array(array(&$this->image,$fname),$argus);
  154. return $this;
  155. }
  156. //获取文字水印功能类: http://phpsdkdoc.duapp.com/?BaeAPI/BaeImageAnnotate.html
  157. public function getAnnotate($text=null){
  158. $this->type = 'Annotate';
  159. $this->image = new BaeImageAnnotate($text);
  160. return $this;
  161. }
  162. //获取图片合成功能类: http://phpsdkdoc.duapp.com/?BaeAPI/BaeImageComposite.html
  163. //多个图片合成反复调用此函数设定参数
  164. public function getComposite($url = NULL){
  165. $this->type = 'Composite';
  166. $this->image[] = new BaeImageComposite($url);
  167. return $this;
  168. }
  169. //获取二维码功能类: http://phpsdkdoc.duapp.com/?BaeAPI/BaeImageQRCode.html
  170. public function getQRCode($text = NULL){
  171. $this->type = 'QRCode';
  172. $this->image = new BaeImageQRCode();
  173. return $this;
  174. }
  175. //获取图形变换处理功能类: http://phpsdkdoc.duapp.com/?BaeAPI/BaeImageTransform.html
  176. public function getTransform(){
  177. $this->type = 'Transform';
  178. $this->image = new BaeImageTransform();
  179. return $this;
  180. }
  181. //获取静态参数: http://phpsdkdoc.duapp.com/?BaeAPI/BaeImageConstant.html
  182. public function get($const=null){
  183. return constant('BaeImageConstant::'. $const);
  184. }
  185. //面向对象调用后的统一执行函数
  186. public function apply(){
  187. if(!isset($this->image) || !isset($this->type)) return -3;//未选择类型
  188. $num = func_num_args();
  189. $params = func_get_args();
  190. switch($this->type){
  191. case 'Annotate':
  192. if($num == 0) return -2;
  193. //params = [url]
  194. $return = $this->Service->applyAnnotateByObject($params[0], $this->image);
  195. break;
  196. case 'Composite':
  197. if($num == 0) return -2;
  198. //params = [width,height,outptcode,quality]
  199. if($num < 4){
  200. $default = array(1000,1000,$this->get('JPG'),80);
  201. foreach($default as $key=>$param){
  202. if(empty($params[$key])) $params[$key] = $param;
  203. }
  204. }
  205. $return = $this->Service->applyCompositeByObject($this->image,$params[0],$params[1],$params[2],$params[3]);
  206. break;
  207. case 'QRCode':
  208. $return = $this->Service->applyQRCodeByObject($this->image);
  209. break;
  210. case 'Transform':
  211. if($num == 0) return -2;//参数错误
  212. //params = [url]
  213. $return = $this->Service->applyTransformByObject($params[0],$this->image);
  214. break;
  215. default:
  216. return -1;//类型错误
  217. }
  218. unset($this->image);
  219. unset($this->type);
  220. //header("Content-type:image/jpg");
  221. //$imageSrc = base64_decode($return['image_data']);
  222. if($return !== false && isset($return['response_params']) && isset($return['response_params']['image_data'])) return $return['response_params'];
  223. //调用error;
  224. return false;
  225. }
  226. public function error(){
  227. return $this->Service->errmsg();
  228. }
  229. }
  230. class FN_platform_baeVCode{
  231. private $image = null;
  232. public function __construct(){
  233. $this->image = new BaeImageService();
  234. }
  235. //生成验证码
  236. public function generateVCode($length,$pattern){
  237. $return = $this->image->generateVCode(array(BaeImageConstant::VCODE_LEN=>$length,BaeImageConstant::VCODE_PATTERN=>$pattern));
  238. //echo "imgurl:" . $return['imgurl'] . "\n";用于显示的url
  239. //echo "secret:" . $return['secret'] . "\n";用于输入后的校验
  240. if($return !== false && isset($return['response_params']) && isset($return['response_params']['imgurl'])) return $return['response_params'];
  241. //调用error;
  242. return false;
  243. }
  244. //校验验证码
  245. public function verifyVCode($input,$secret){
  246. $return = $this->image->verifyVCode(array(BaeImageConstant::VCODE_INPUT=>$input,BaeImageConstant::VCODE_SECRET=>$secret));
  247. if($return !== false && isset($return['response_params']) && isset($return['response_params']['imgurl'])) return $return['response_params'];
  248. //调用error;
  249. return false;
  250. }
  251. public function error(){
  252. return $this->Service->errmsg();
  253. }
  254. }
  255. //暂无权限接口设计
  256. class FN_platform_baeStorage extends FN_tools_rest{
  257. private $accesskey = null;
  258. private $securekey = null;
  259. private $bucket = null;
  260. const DEFAULT_URL = 'http://bcs.duapp.com';
  261. protected function init(){
  262. $this->accesskey = $this->config['accesskey'];
  263. $this->securekey = $this->config['securekey'];
  264. }
  265. /**
  266. * 校验bucket是否合法,bucket规范
  267. * 1. 由小写字母,数字和横线'-'组成,长度为6~63位
  268. * 2. 不能以数字作为Bucket开头
  269. * 3. 不能以'-'作为Bucket的开头或者结尾
  270. * @param string $bucket
  271. * @return boolean
  272. */
  273. public static function validate_bucket($bucket) {
  274. //bucket 正则
  275. $pattern1 = '/^[a-z][-a-z0-9]{4,61}[a-z0-9]$/';
  276. if (! preg_match ( $pattern1, $bucket )) {
  277. return false;
  278. }
  279. return true;
  280. }
  281. //创建bucket
  282. public function creatDir($dirname,$acl='public-read'){
  283. if(!$this->validate_bucket($dirname)) return false;
  284. $sign = $this->sign('PUT',$dirname,'');
  285. $url = $this->formatURL($dirname,'');
  286. $params = array('sign'=>$sign);
  287. $header = array('x-bs-acl'=>$acl);
  288. $options = array('header'=>$header);
  289. $response = $this->put($url,$params,$options);
  290. return $response->isOK();
  291. }
  292. //列出所有bucket
  293. public function listDir(){
  294. $sign = $this->sign('GET','','');
  295. $url = $this->formatURL('','');
  296. $params = array('sign'=>$sign);
  297. $response = $this->get($url,$params);
  298. return $response->isOK() ? $response->getBodyJson():false;
  299. }
  300. //删除bucket
  301. public function deleteDir($dirname){
  302. $sign = $this->sign('DELETE',$dirname,'');
  303. $url = $this->formatURL($dirname,'');
  304. $params = array('sign'=>$sign);
  305. $response = $this->delete($url,$params);
  306. return $response->isOK();
  307. }
  308. //设置文件操作的bucket
  309. public function setDir($dirname){
  310. $this->bucket = $dirname;
  311. }
  312. //添加object
  313. public function addFile($filename,$file,$acl=false,$header=array()){
  314. $sign = $this->sign('PUT',$this->bucket,$filename);
  315. $url = $this->formatURL($this->bucket,$filename);
  316. $params = array('sign'=>$sign);
  317. if ($acl) {
  318. $header['x-bs-acl'] = $acl;
  319. }
  320. $options = array('header'=>$header);
  321. $options ['fileUpload'] = $file;
  322. $head['Content-Disposition'] = 'attachment; filename='.substr($filename,0,strrpos($filename,'/'));
  323. $response = $this->put ($url,$params,$options);
  324. return $response->isOK ();
  325. }
  326. //添加object通过byte
  327. public function addFileBytes($filename,$bytes,$acl=false,$header=array()){
  328. $sign = $this->sign('PUT',$this->bucket,$filename);
  329. $url = $this->formatURL($this->bucket,$filename);
  330. $params = array('sign'=>$sign);
  331. if ($acl) {
  332. $header['x-bs-acl'] = $acl;
  333. }
  334. $options = array('header'=>$header);
  335. $options ['content'] = $bytes;
  336. $head['Content-Disposition'] = 'attachment; filename='.substr($filename,0,strrpos($filename,'/'));
  337. $response = $this->put ($url,$params,$options);
  338. return $response->isOK ();
  339. }
  340. //复制object
  341. public function copyFile($source,$filename,$etag=false){
  342. $source = $this->parseURL($source);
  343. $sign = $this->sign('PUT',$this->bucket,$filename);
  344. $url = $this->formatURL($this->bucket,$filename);
  345. $params = array('sign'=>$sign);
  346. $header = array('x-bs-copy-source'=>$this->formatURL($source['bucket'],$source['object']));
  347. if($etag) $header['x-bs-copy-source-tag'] = $etag;
  348. $options = array('header'=>$header);
  349. $response = $this->put($url,$params,$options);
  350. return $response->isOK();
  351. }
  352. //删除object
  353. public function deleteFile($filename){
  354. $sign = $this->sign('DELETE',$this->bucket,$filename);
  355. $url = $this->formatURL($this->bucket,$filename);
  356. $params = array('sign'=>$sign);
  357. $response = $this->delete($url,$params);
  358. return $response->isOK();
  359. }
  360. //列出所有object
  361. //prefix可以作为路劲参数设置
  362. public function listFile($prefix = '',$start=0,$limit=0,$list_model = 2) {
  363. $sign = $this->sign('GET',$this->bucket,'');
  364. $url = $this->formatURL($this->bucket,'');
  365. $params = array('sign'=>$sign);
  366. if ($start) {
  367. $params['start'] = $start;
  368. }
  369. if ($limit) {
  370. $params['limit'] = $limit;
  371. }
  372. $params['prefix'] = rawurlencode ('/'. $prefix );
  373. $params['dir'] = $list_model;
  374. $response = $this->get($url,$params);
  375. return $response->isOK() ? $response->getBodyJson():false;
  376. }
  377. //获取object元数据
  378. public function getHead($filename,$header=array()){
  379. $sign = $this->sign('HEAD',$this->bucket,$filename);
  380. $url = $this->formatURL($this->bucket,$filename);
  381. $params = array('sign'=>$sign);
  382. $options = array('header'=>$header);
  383. $response = $this->head($url,$params,$options);
  384. return $response->isOK() ? $response->getHeader() : false;
  385. }
  386. //获取object
  387. public function getFile($filename,$range=false,$header=array()){
  388. $sign = $this->sign('HEAD',$this->bucket,$filename);
  389. $url = $this->formatURL($this->bucket,$filename);
  390. $params = array('sign'=>$sign);
  391. if(is_array($range)) {
  392. $header['Range'] = $range[0].'-'.($range[1] ? $range[1] : 'end');
  393. }elseif($range){
  394. $header['Range'] = '0-'.$range;
  395. }
  396. $options = array('header'=>$header);
  397. $response = $this->head($url,$params,$options);
  398. return $response->isOK() ? $response->getBody() : false;
  399. }
  400. //返回当前基本url
  401. public function getURL(){
  402. return self::DEFAULT_URL.'/' . $this->bucket.'/';
  403. }
  404. /**
  405. * 构造url
  406. * @param string $bucket
  407. * @param string $object
  408. * @return boolean string
  409. */
  410. private function formatURL($bucket,$object) {
  411. return self::DEFAULT_URL.'/' . $bucket.'/' . rawurlencode ( $object );
  412. }
  413. /**
  414. * 解析url为百度的bucket+object
  415. * @param string $url
  416. * @return boolean string
  417. */
  418. private function parseURL($url) {
  419. $url = str_replace(self::DEFAULT_URL.'/','',$url);
  420. $pos = strpos($url,'/');
  421. $bucket = substr($url,0,$pos-1);
  422. $object = substr($url,$pos);
  423. return array('bucket'=>$bucket,'object'=>$object);
  424. }
  425. //生成签名
  426. //time为有效时间,Unix时间戳
  427. //ip访问白名单
  428. //size限制上传object大小,单位B
  429. private function sign($method,$bucket,$object,$time=false,$ip=false,$size=false){
  430. $flag = 'MBO';
  431. $content = 'Method='.$method.'\n'
  432. .'Bucket='.$bucket.'\n'
  433. .'Object=/'.$object.'\n';
  434. if($time){
  435. $flag.='T';
  436. $content .= 'Time='.$time.'\n';
  437. }
  438. if($ip){
  439. $flag.='I';
  440. $content .= 'Ip='.$ip.'\n';
  441. }
  442. if($size){
  443. $flag.='S';
  444. $content .= 'Size='.$size.'\n';
  445. }
  446. $content = $flag.'\n'.$content;
  447. $signature=urlencode(base64_encode(hash_hmac('sha1',$content, $this->secretKey,true)));
  448. return $flag.':'.$this->accesskey.':'.$signature;
  449. }
  450. }
  451. class FN_platform_baeQueue extends FN_tools_rest{
  452. protected $accesskey = null;
  453. protected $securekey = null;
  454. private $queue = null;
  455. const DEFAULT_URL = 'http://bcms.api.duapp.com/rest/2.0/bcms';
  456. protected function init(){
  457. $this->accesskey = $this->config['accesskey'];
  458. $this->securekey = $this->config['securekey'];
  459. }
  460. public function setQueue($queuename){
  461. $this->queue = $queuename;
  462. }
  463. /**
  464. * 构造url
  465. * @return boolean string
  466. */
  467. protected function formatURL() {
  468. return self::DEFAULT_URL.'/' . $this->queue;
  469. }
  470. //生成签名
  471. protected function sign($method,$url,$params){
  472. $basic_string = $method.$url;
  473. sort($params);
  474. foreach($params as $key=>$value){
  475. $basic_string .= $key.'='.$value;
  476. }
  477. $basic_string .= $this->securekey;
  478. return md5((urlencode($basic_string)));
  479. }
  480. //统一请求函数
  481. protected function requestProxy($params){
  482. //access_token string  是 开发者准入token,https调用时必须存在
  483. $url = $this->formatURL();
  484. $params['client_id'] = $this->accesskey;
  485. $params['timestamp'] = FNbase::getTime();
  486. $sign = $this->sign('POST',$url,$params);
  487. $params['sign'] = $sign;
  488. $header = array();
  489. $header['Host'] = 'bcms.api.duapp.com';
  490. $header['Content-Type'] = 'application/x-www-form-urlencoded';
  491. $options = array('header'=>$header);
  492. $options['method'] = $params['method'];
  493. $options['url'] = $url;
  494. if($params['method'] == 'GET'){
  495. $options['url'] = $this->combineURL($options['url'],$params);
  496. }else{
  497. $options['content'] = $this->combineParams($params);
  498. }
  499. $response = $this->request($options);
  500. return $response->isOK() ? $response->getBodyJson():false;
  501. }
  502. }
  503. class FN_platform_baeMail extends FN_platform_baeQueue{
  504. private $from = null;
  505. protected function init(){
  506. parent::init();
  507. if(isset($this->config['queue'])) $this->setQueue($this->config['queue']);
  508. $this->setFrom($this->config['from']);
  509. }
  510. public function setFrom($from){
  511. $this->from = $from;
  512. }
  513. public function mail($address,$subject,$message,$ishtml=false){
  514. if(is_array($address)){
  515. $address = json_encode($address);
  516. }
  517. $params['address'] = $address;
  518. $params['method'] = 'mail';
  519. $params['message'] = ($ishtml ? ' <!--HTML-->':'').$message;//如果是二进制内容,需要将内容先做BASE64编码成文本再发布消息
  520. $params['mail_subject'] = $subject;
  521. if($this->from) $params['from'] = $this->from;
  522. return $this->requestProxy($params);
  523. }
  524. }
  525. class FN_platform_beaChannel extends FN_tools_rest{
  526. protected $accesskey = null;
  527. protected $securekey = null;
  528. const DEFAULT_URL = 'http://channel.api.duapp.com/rest/2.0/channel';
  529. protected function init(){
  530. $this->accesskey = $this->config['accesskey'];
  531. $this->securekey = $this->config['securekey'];
  532. }
  533. /**
  534. * 构造url
  535. * @param string $channel
  536. * @return boolean string
  537. */
  538. protected function formatURL($channel) {
  539. return self::DEFAULT_URL.'/' . $channel;
  540. }
  541. //生成签名
  542. protected function sign($method,$url,$params){
  543. $basic_string = $method.$url;
  544. sort($params);
  545. foreach($params as $key=>$value){
  546. $basic_string .= $key.'='.$value;
  547. }
  548. $basic_string .= $this->securekey;
  549. return md5((urlencode($basic_string)));
  550. }
  551. //统一请求函数
  552. protected function requestProxy($params,$channel){
  553. $url = $this->formatURL($channel);
  554. $params['apikey'] = $this->accesskey;
  555. $params['timestamp'] = FNbase::getTime();
  556. $sign = $this->sign('POST',$url,$params);
  557. $params['sign'] = $sign;
  558. $options = array();
  559. $options['url'] = $url;
  560. $options['method'] = $params['method'];
  561. if($params['method'] == 'GET'){
  562. $options['url'] = $this->combineURL($options['url'],$params);
  563. }else{
  564. $options['content'] = $this->combineParams($params);
  565. }
  566. $response = $this->request($options);
  567. return $response->isOK() ? $response->getBodyJson():false;
  568. }
  569. }