您好,登錄后才能下訂單哦!
這篇文章給大家介紹利用PHP怎么將圖片上傳到服務器中,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
一、當下問題
1、在我們已有的A項目中,新增一個添加商品的功能,這個本來是沒有什么問題的,因為目前A項目中本身就已經連接了B項目的數據庫,所以商品屬性的新增和修改都沒什么問題。主要是商品圖片的上傳這里,有點問題。B項目已經對外提供了上傳圖片的接口,但是由于我確實對前端不是特別熟悉。所以在A項目中的后臺JS中調取B項目的上傳圖片的接口時,一直提示"CORS",這里應該是存在一個跨域的問題,雖然我PHP接口端已經對跨域做了處理(入口文件處),但是貌似JS這邊也需要相應的調整。
// [ 應用入口文件 ] //入口文件index.php namespace think; // 加載基礎文件 require __DIR__ . '/thinkphp/base.php'; // 支持事先使用靜態方法設置Request對象和Config對象 header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Headers: Content-Type,XFILENAME,XFILECATEGORY,XFILESIZE,authorization"); // 執行應用并響應 Container::get('app')->bind('api')->run()->send();
2、無奈小白JS功底不夠扎實,所以我這邊準備通過A項目中調取后臺PHP接口,然后通過在PHP代碼中接受web端參數,然后再轉發,調取B項目中上傳圖片的接口,試圖完成功能。于是先通過Postman接口工具測試了一下B項目上傳圖片的接口是否有效。如圖3,發現確實沒有什么問題,于是就準備如此處理。
3、但是實際是,在調取時,我們常用的傳參數方式是GET或者POST方式,但是我們知道文件上傳是通過$_FILES接受,下面是B項目的上傳圖片的控制器代碼(用的是TP5.1),接受是通過內置的file方式。
/**上傳圖片 * @param Request $request */ public function uploadImg(Request $request){ $file = $request->file('image'); $type = $request->post('type', 0); // 移動到框架應用根目錄/uploads/ 目錄下 $upload_path = config('common.upload_path'); switch ($type) { case 1://門店 $path = $upload_path['shop_img']; break; case 2://投票活動 $path = $upload_path['vote_img']; break; case 3://投票活動參賽圖片 $path = $upload_path['vote_contestant_img']; break; case 4://會員店鋪logo圖片 $path = $upload_path['member_shop']; break; case 5://自營商品圖片 $path = $upload_path['self_goods']; break; default: $path = $upload_path['common']; break; } $save_path = env('root_path').$path; $info = $file->validate(['ext'=>'jpg,jpeg,png,gif'])->move($save_path); if($info){ $return = [ 'extension' => $info->getExtension(), 'image_path' => $path.$info->getSaveName(), 'image_name' => $info->getFilename(), ]; $this->apiResult(CustomError::OPERATION_SUCCSESS, $return); }else{ $this->apiResult(CustomError::OPERATION_FAILED, [], $file->getError()); } }
4、所以在轉發A項目web端傳來的,文件內容,就有點不知所措了。該死,該死。
//文件上傳接受參數 array(1) { ["file_upload"] => array(5) { ["name"] => string(8) "timg.jpg" ["type"] => string(10) "image/jpeg" ["tmp_name"] => string(22) "C:\Windows\php73CE.tmp" ["error"] => int(0) ["size"] => int(355565) } }
5、所以按剛才設想的,簡單做下轉發還是不行,這里面參數的傳輸方式應該還有另外一種,就是文件的類型。鑒于是通過Postman方式上傳成功,這個工具確實很推薦多多學習,他不僅作為一個第三方中間為我們驗證接口是否可用,更給我們提供了調取接口的各種代碼Damo,如圖3中標識的Code處,就是獲取Damo的按鈕。我們點擊可以看見Postman給我提供了三種,調取接口的方式。
<?php //1、HttpRequest 發送http請求 $request = new HttpRequest(); $request->setUrl('http://jszapi.dev.jingjinglego.com/index.php/index/uploadImg'); $request->setMethod(HTTP_METH_POST); $request->setHeaders(array( 'cache-control' => 'no-cache', 'Connection' => 'keep-alive', 'Content-Length' => '39091', 'Content-Type' => 'multipart/form-data; boundary=--------------------------296608706222243058746908', 'Accept-Encoding' => 'gzip, deflate', 'Host' => 'jszapi.dev.jingjinglego.com', 'Postman-Token' => 'dc010150-b166-4dec-a33f-959a65c91c71,be7315cb-ae21-404f-89fa-dddf5973eb3a', 'Cache-Control' => 'no-cache', 'Accept' => '*/*', 'User-Agent' => 'PostmanRuntime/7.15.2', 'content-type' => 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' )); $request->setBody('------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="image"; filename="785da43beca5a474.jpg" Content-Type: image/jpeg ------WebKitFormBoundary7MA4YWxkTrZu0gW--'); try { $response = $request->send(); echo $response->getBody(); } catch (HttpException $ex) { echo $ex; }
<?php //2、pecl_http 需要開啟PECL HTTP 擴展 $client = new http\Client; $request = new http\Client\Request; $body = new http\Message\Body; $body->addForm(NULL, array( array( 'name' => 'image', 'type' => null, 'file' => '/E:/MyBooks/網站圖標/網站素材/785da43beca5a474.jpg', 'data' => null ) )); $request->setRequestUrl('http://jszapi.dev.jingjinglego.com/index.php/index/uploadImg'); $request->setRequestMethod('POST'); $request->setBody($body); $request->setHeaders(array( 'cache-control' => 'no-cache', 'Connection' => 'keep-alive', 'Content-Length' => '39091', 'Content-Type' => 'multipart/form-data; boundary=--------------------------296608706222243058746908', 'Accept-Encoding' => 'gzip, deflate', 'Host' => 'jszapi.dev.jingjinglego.com', 'Postman-Token' => 'dc010150-b166-4dec-a33f-959a65c91c71,3216cc22-be61-4d4b-8d41-c5178848b54f', 'Cache-Control' => 'no-cache', 'Accept' => '*/*', 'User-Agent' => 'PostmanRuntime/7.15.2' )); $client->enqueue($request)->send(); $response = $client->getResponse(); echo $response->getBody();
<?php //3、cURL 是一個非常強大的開源庫,支持很多協議,包括HTTP、FTP、TELNET等,我們使用它來發送HTTP請求。//它給我們帶來的好處是可以通過靈活的選項設置不同的HTTP協議參數,并且支持HTTPS。CURL可以根據URL前綴是“HTTP” 還是“HTTPS”自動選擇是否加密發送內容。 $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => "http://jszapi.dev.jingjinglego.com/index.php/index/uploadImg", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"image\"; filename=\"785da43beca5a474.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--", CURLOPT_HTTPHEADER => array( "Accept: */*", "Accept-Encoding: gzip, deflate", "Cache-Control: no-cache", "Connection: keep-alive", "Content-Length: 39091", "Content-Type: multipart/form-data; boundary=--------------------------296608706222243058746908", "Host: jszapi.dev.jingjinglego.com", "Postman-Token: dc010150-b166-4dec-a33f-959a65c91c71,982e059e-bd8b-4db9-83c4-3fd52c8ed82f", "User-Agent: PostmanRuntime/7.15.2", "cache-control: no-cache", "content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" ), )); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response; }
6、如上面3個代碼片段,但是后來驗證后,發現1/3的參數,不知道是怎么傳輸的,2的參數很容易看懂,但是運用的話需要開啟擴展,這個目前不太合適,所以┭┮﹏┭┮。
二、寫在心里
1、這個上傳的問題,確實卡住了,感覺有點難過。其實每次都會遇見一個自己的困難,經常遇見,周末下午的時候,我在家打開電腦,打來遠程,準備登陸下ftp拉下代碼,發現一直連不上,心里那個煩啊。但是還是通過遠程工具(向日葵),將代碼拉下來了。想這個圖片上傳到底怎么弄了,之前也看過,關于通過ftp的方式上傳圖片,但是后來查看了相關文章需要在php.ini中開啟,所以也作罷。
#開啟ftp擴展支持 extension=php_ftp.dll
2、經常遇見困難,經常覺得自己很LOW但是,已經工作了這么久,發現其實問題最后又都解決了,但是現在回想,卻忘了到底是怎么解決的,所以寫這個博文主要也是想記錄下。一直到下午4點多,深圳的天氣今年悶熱居多,中午我已經昧著良心午休了1個小時,所以現在到現在心里還有些許內疚,唉。
3、但是還是找不到解決的方法,頭疼的厲害,好熱。怎么辦,我決定靠在椅子上休息下,于是我還是決定躺在沙發上睡會。剛躺下,想著這怎么辦呢。
-----------------------base64---------------------------華麗的分割線
我突然想到了base64這個讀起來,朗朗上口的函數,對如果現將圖片轉換成base64字符串,再通過POST方式傳送給B項目,然后再B項目中對字符串進行解碼,生成圖片,保存到B項目,然后返回圖片路徑,不就可以了嗎。于是我有推了一遍,發現沒有疏忽。于是覺得應該是解決了。
三、解決圖片上傳問題
1、A接受web傳來圖片臨時文件,
#上傳圖片京手指 1:圖片保留到本地 public function uploadJszImg() {$path = config('business.jsz_file_tem'); $file = request()->file('file_upload'); $info = $file->validate(['ext'=>'jpg,jpeg,png,gif'])->move($path);//圖片保存到本地 $img_one = $path.$info->getSaveName();//圖片路徑 $img_base = imgToBase64($img_one);//獲取圖片base64編碼格式 deleteFileWay($path);//刪除臨時文件 $url = config('business.jsz_api')['baseImg']; $data = [ 'base_string'=> $img_base, 'path' => 'upload/goods_img', ]; $res = http_api($url,$data,1); $res = json_decode($res,true); if($res['data']){ $return = ['code'=>1,'message'=>'成功','data'=>'jszapi.dev.jingjinglego.com'.$res['data']]; }else{ $return = ['code'=>0,'message'=>'失敗']; } return $return; }
2、并轉換成base64字符串,
/** * 獲取圖片的Base64編碼(不支持url) * @param $img_file 傳入本地圖片地址 * @return string */ function imgToBase64($img_file) { $img_base64 = ''; if (file_exists($img_file)) { $app_img_file = $img_file; // 圖片路徑 $img_info = getimagesize($app_img_file); // 取得圖片的大小,類型等 //echo '<pre>' . print_r($img_info, true) . '</pre><br>'; $fp = fopen($app_img_file, "r"); // 圖片是否可讀權限 if ($fp) { $filesize = filesize($app_img_file); $content = fread($fp, $filesize); $file_content = chunk_split(base64_encode($content)); // base64編碼 switch ($img_info[2]) { //判讀圖片類型 case 1: $img_type = "gif"; break; case 2: $img_type = "jpg"; break; case 3: $img_type = "png"; break; } $img_base64 = 'data:image/' . $img_type . ';base64,' . $file_content;//合成圖片的base64編碼 } fclose($fp); } return $img_base64; //返回圖片的base64 }
3、B接受A項目傳來參數
/** * 將base64字符串轉換成圖片并保存在本地 * @param Request $request * @return void */ public function baseImg(Request $request) { $base_string = $request->post('base_string', ''); if (!$base_string) { $this->apiResult(CustomError::MISSING_PARAMS); } $path = $request->post('path', ''); if (!$path) { $this->apiResult(CustomError::MISSING_PARAMS); } $request = base64_image_content($base_string, $path);//解碼 if($request){ $this->apiResult(CustomError::OPERATION_SUCCSESS, $request); }else{ $this->apiResult(CustomError::OPERATION_FAILED); } }
4、對字符解析解碼
/** * [將Base64圖片轉換為本地圖片并保存] * @param [Base64] $base64_image_content [要保存的Base64] * @param [目錄] $path [要保存的路徑] */ function base64_image_content($base64_image_content,$path){ //匹配出圖片的格式 if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){ $type = $result[2]; $new_file = $path."/".date('Ymd',time())."/"; if(!file_exists($new_file)){ //檢查是否有該文件夾,如果沒有就創建,并給予最高權限 mkdir($new_file, 0700); } $new_file = $new_file.time().".{$type}"; if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))){ return '/'.$new_file; }else{ return false; } }else{ return false; } }
5、最后返回上傳好的圖片路徑
關于利用PHP怎么將圖片上傳到服務器中就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。