首页 > 淘宝TFS PHP如何调用API?

淘宝TFS PHP如何调用API?

如下,PHP 上传图片到淘宝TFS图片服务器,能返回元数据,但是图片预览乱码

<?php
    /**
     * Email net.webjoy@gmail.com
     * author jackluo
     * 2014.11.21
     * 
     */

    //*
    function curl_post($url, $data, $header = array()){
            if(function_exists('curl_init')) {
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $url);
                if(is_array($header) && !empty($header)){
                    $set_head = array();
                    foreach ($header as $k=>$v){
                        $set_head[] = "$k:$v";
                    }
                    curl_setopt($ch, CURLOPT_HTTPHEADER, $set_head);
                }
                curl_setopt($ch, CURLOPT_HEADER, 0);
                curl_setopt($ch, CURLOPT_POST, 1);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($ch, CURLOPT_TIMEOUT, 1);// 1s to timeout.
                $response = curl_exec($ch);
                if(curl_errno($ch)){
                    //error
                    return curl_error($ch);
                }
                $reslut = curl_getinfo($ch);
                print_r($reslut);
                curl_close($ch);
                $info = array();
                if($response){
                    $info = json_decode($response, true);
                }
                return $info;
            } else {
                throw new Exception('Do not support CURL function.');
            }
    }
    //*/
    //  
    function api_notice_increment($url, $data)
    {
        $ch = curl_init();        
        curl_setopt($ch, CURLOPT_HEADER,0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1);
//        $data = http_build_query($data);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        //curl_file_create
    //    $result =  curl_exec($ch);
        $lst['rst'] = curl_exec($ch);
        $lst['info'] = curl_getinfo($ch);
        curl_close($ch); 
    
        return $lst;
    //    return $result;
    }

     /**
         *  curl文件上传
         *  @var  struing  $r_file  上传文件的路劲和文件名  
         *     
         */
    /*     
    function upload_file($url,$r_file)
     {
        $file = array("fax_file"=>'@'.$r_file,'type'=>'image/jpeg');//文件路径,前面要加@,表明是文件上传.
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL,$url);
        curl_setopt($curl,CURLOPT_POST,1);
        curl_setopt($curl,CURLOPT_POSTFIELDS,$file);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        $result = curl_exec($curl);  //$result 获取页面信息 
        curl_close($curl);
        echo $result ; //输出 页面结果
   }*/
    
   function upload_file($url,$filename,$path,$type){
        $data = array(
            'pic'=>'@'.realpath($path).";type=".$type.";filename=".$filename
        );
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true );
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_getinfo($ch);
        $return_data = curl_exec($ch);
        curl_close($ch);
        echo $return_data;       
   }




    if ($_POST) {
        $url = '169.57.13.186:8080/v1/tfs?suffix=.jpg&simple_name=1';
        //

/*
        print_r($_FILES);
        exit;
*/
        //$filename = $path."/232.jpg";
        //upload tmp
        $tmpname = $_FILES['fname']['name'];
        $tmpfile = $_FILES['fname']['tmp_name'];
        $tmpType = $_FILES['fname']['type'];
//        echo $tmpType;
        upload_file($url,$tmpname,$tmpfile,$tmpType);
        /*
        $data = array(
                'path'=>"@$path/232.jpg",
                'name'=>'h'
        );
        */
        //'pic'=>'@/tmp/tmp.jpg', 'filename'=>'tmp'
        //$data = array('pic'=>"@$filename", 'filename'=>'tmp');
/*
        $data = array(
            'uid'    =>    10086,
            'pic'    =>    '@$tmpfile'.';type='.$tmpType
        );
        $info = api_notice_increment($url, $data);
*/
        //$info = curl_post($url, $data);
        //$info = api_notice_increment($url, $data);
        //upload_file($url,$tmpfile);
        //print_r($info);
        exit;
/*
        $file = 'H:\www\test\psuCARGLSPA-pola.jpg'; //要上传的文件
        $src = upload_curl_pic($file);
        echo $src;
*/
    }    
?>



<form action="http://localhost/upload.php" enctype="multipart/form-data"  method="post">
  <p>UpLoad: <input type="text" name="fname" /></p>
  <p>UpLoad: <input type="file" name="fname" /></p>

  <input type="submit" value="Submit" />
</form>



乱码在于你图片中包含了http 响应头信息,把响应头信息去掉就可以了

curl_setopt($ch, CURLOPT_HEADER, false);

不知道你在哪儿复制的代码,里面两个没用到的函数,主要问题是在:

php$data = array(
            'pic'=>'@'.realpath($path).";type=".$type.";filename=".$filename
        );

只需要@+服务器上的图片路径就可以了。
整理修改了下,已测:

php<?php
if ($_POST) {
    $url = '169.57.13.186:8080/v1/tfs?suffix=.jpg&simple_name=1';
    $tmpfile = $_FILES['fname']['tmp_name'];
    $data = array(
        'pic'=>'@'.$tmpfile
    );
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true );
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_getinfo($ch);
    $return_data = curl_exec($ch);
    curl_close($ch);
    echo $return_data;
    exit;
}
?>



<form action="?" enctype="multipart/form-data"  method="post">
  <p>UpLoad: <input type="text" name="fname" /></p>
  <p>UpLoad: <input type="file" name="fname" /></p>

  <input type="submit" value="Submit" />
</form>



TFS服务器是保存的你HTTP请求中, POST 的内容,所以你按上传文件的格式发请求,你最后记录下来的内容就是你POST上传时的请求体.

试试下面这样的.

<?php

if(isset($_FILES['fname'])){

    $url = 'http://169.57.13.186:8080/v1/tfs?suffix=.jpg&simple_name=1';

    //要提交至TFS服务器的数据
    $data = file_get_contents($_FILES['fname']['tmp_name']);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true );
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_HEADER, false);
    //指定上传的文件类型(非必须)
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Content-Type: ' . $_FILES['fname']['type']
    ));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_getinfo($ch);
    $return_data = curl_exec($ch);
    curl_close($ch);


    $ret = json_decode($return_data, TRUE);

    if($ret !== NULL){
        echo '<img src="http://img1.comprame.com/v1/tfs/'. $ret['TFS_FILE_NAME'] . '" />';
    }else{
        echo $return_data;
    }
}
?>


<form action='?' enctype='multipart/form-data'  method='post'>
  <p>UpLoad: <input type='file' name='fname' /></p>
  <input type='submit' value='Submit' />
</form>


效果演示:

如果要上传的文件是在本地, 而不是由表单提交上来的, 代码修改如下:

//要提交至TFS服务器的数据
    $data = file_get_contents($_FILES['fname']['tmp_name']);

改为

    //要上传的图片是本地的文件时,使用 `file_get_contents` 得到内容,然后上传.
    $data = file_get_content('X:\xxx.png');

=================我还是分隔线====================

根据楼主在评论中的补充,花了几分钟写一个PHP的class, 代码及测试用例如下:

<?php
/*
    Author: xqin
    Email: dds_feng@qq.com
    根据 TFS RESTful API ( https://github.com/alibaba/nginx-tfs/blob/master/TFS_RESTful_API.markdown )
    编写而成的 TFS RESTful API Client, 版权没有, 使用时爱带不带, 本注释想删除就删除.
    遇到问题请自行解决, 当然Email我也是可以的.
*/


class TFSClient{

    private $API_URL;

    function TFSClient($host, $ver='v1', $appkey='tfs'){
        $this->API_URL = sprintf('%s/%s/%s', $host, $ver, $appkey);
    }

    private function Request($action='', $method='GET', $data=null){

        $ch = curl_init($this->API_URL . $action);

        //指定 HTTP 请求的 Method
        curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, $method);

        //设定CURL请求的超时时间(当你需要上传或者获取比较大的文件时,可以将超时时间设置的大一点,以防止文件没操作完成,但超过超时时间之后出现问题)
        curl_setopt($ch, CURLOPT_TIMEOUT, 120);//单位秒(此处设定为2分钟)

        if($data !== null){
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            //去除自带的这两个 HTTP请求头
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                    'Content-Type:', 'Accept:'
            ));
        }else{
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                    'Accept: '
            ));
        }

        //将得到的内容通过 curl_exec 返回, 而不是直接输出
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        //curl_exec 返回的内容不要包含HTTP响应头
        curl_setopt($ch, CURLOPT_HEADER, false);
        $return_data = curl_exec($ch);
        curl_close($ch);

        return $return_data;
    }

    //返回保存后的文件名,如果保存失败, 则返回 FALSE
    public function SaveFile($data, $parameter=''){
        $ret = $this->Request($parameter, 'POST', $data);

        $ret = json_decode($ret, TRUE);

        //解析 json 字符串失败, 或者返回的内容中没有 TFS_FILE_NAME, 则认为保存失败
        if($ret === NULL || !isset($ret['TFS_FILE_NAME'])){
            return FALSE;
        }

        return $ret['TFS_FILE_NAME'];
    }

    //返回更新后的文件名,如果更新失败, 则返回 FALSE
    //$filename 旧的文件名(即你要更新哪个文件的文件名)
    //$data 要更新的内容是什么
    //$parameter 设置更新后的文件时访问所需要的参数
    public function UpdateFile($filename, $data, $parameter=''){
        $ret = $this->Request(sprintf('/%s%s', $filename, $parameter), 'PUT', $data);

        $ret = json_decode($ret, TRUE);

        //解析 json 字符串失败, 或者返回的内容中没有 TFS_FILE_NAME, 则认为保存失败
        if($ret === NULL || !isset($ret['TFS_FILE_NAME'])){
            return FALSE;
        }

        return $ret['TFS_FILE_NAME'];
    }

    //从TFS服务器上获取文件
    public function ReadFile($filename){
        return $this->Request(sprintf('/%s', $filename), 'GET');
    }

    //从TFS服务器上删除文件
    public function DeleteFile($filename){
        $this->Request(sprintf('/%s', $filename), 'DELETE');
    }
}





$tfs = new TFSClient(
    'http://169.57.13.186:8080',    //API主机地址
    'v1',//版本
    'tfs'//AppKey
);



//测试代码, 自动生成要上传的文件
$tf1 = __DIR__ .'/test1.txt';
$tf2 = __DIR__ . '/test2.txt';

//写入文件内容
file_put_contents($tf1, 'HelloWorld!!!!!');
file_put_contents($tf2, 'HelloWorld, Again!!!!!' . time());



//保存文件至TFS上
//使用 .txt 的扩展名保存文件(suffix=.txt), 并且要求访问时必须带正确的后缀才可以访问存入的文件(simple_name=1)
//第二个参数中的内容, 请根据 TFS RESTful API 中的说明并根据自己的需要做相应的修改, 此处只是根据你之前提供的代码做演示
$result = $tfs->SaveFile(file_get_contents($tf1), '?suffix=.txt&simple_name=1');


if($result === FALSE){
    exit('文件保存失败!');
}

$filename = $result;
echo "上传成功后的文件名为: ", $filename, "\n";


//从TFS服务器上读取文件
$f = $tfs->ReadFile($filename);

//将读取到的文件写入到本地
file_put_contents(__DIR__ . '/ntest1.txt', $f);




//更新文件至TFS上
$result = $tfs->UpdateFile($filename, file_get_contents($tf2));

if($result === FALSE){
    exit('更新文件失败!');
}

$filename = $result;
echo "更新后的文件名为: ", $filename, "\n";

//从TFS服务器上读取文件
$f = $tfs->ReadFile($filename);
//将读取到的文件写入到本地
file_put_contents(__DIR__ . '/ntest2.txt', $f);



//输出上传/下载下来的文件的MD5值
$files = array('test1.txt', 'ntest1.txt', 'test2.txt', 'ntest2.txt');

foreach($files as $f){
    echo __DIR__ . '/' . $f, "\t", md5(file_get_contents(__DIR__ . '/'. $f)), "\n";
}



//删除更新后的文件
$tfs->DeleteFile($filename);

//尝试读取刚才删除的文件
$f = $tfs->ReadFile($filename);

//会输出 404, 因为文件被删除了, 不存在了, 根据 TFS RESTful API 文档中的定义, 服务器返回  404 Not Found
echo $f;

运行效果如(运行环境: PHP 5.6.9 (cli) (built: May 13 2015 19:28:50)):

PS: 本人的专职工种是写javascript的, 非职业 PHP 选手, 上面的代码请轻喷, 谢谢合作.

【热门文章】
【热门文章】