您好,登錄后才能下訂單哦!
云函數SCF中PHP的入門坑有哪些,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
由于云函數 SCF 本身是用 bootstrap.php
來調用我們的入口函數,默認為 index.main\_handler
,意思是調用 index.php
文件中的 main\_handler()
,所以很多地方寫法要有改變。php 一般提供網頁服務,所以我主要講API 網關配合的云函數 SCF。
main_handler($event, $context)函數會傳入2個參數,首先這2個參數是object,需要用->來訪問子項,如 $event->{'headers'} ,不是很方便,我一般轉換成數組:
$event = json_decode(json_encode($event), true);
這樣就比較方便了,如 $event['headers']['host'] 。
大家可以打印這兩個參數看一眼里面有些什么。
我們可以從中獲取到很多有用的東西,比如:
$_GET = $event['queryString']; $_POST = $event['body']; $_COOKIE = $event['headers']['cookie'];
在云函數 SCF 中運行的 php 程序,因為瀏覽器是提交給 API 網關,不是提交給 SCF 的,這些超全局變量完全沒有獲取到東西,所以要這樣來獲取。
但我們發現,$event['body']
與 $event['headers']['cookie']
本身是一個長字符串,里面有好幾個值,并且里面 url 編碼了,這樣不方便使用,所以做些小操作:
$postbody = explode("&",$event['body']); foreach ($postbody as $postvalues) { $pos = strpos($postvalues,"="); $_POST[urldecode(substr($postvalues,0,$pos))]=urldecode(substr($postvalues,$pos+1)); } $cookiebody = explode("; ",$event['headers']['cookie']); foreach ($cookiebody as $cookievalues) { $pos = strpos($cookievalues,"="); $_COOKIE[urldecode(substr($cookievalues,0,$pos))]=urldecode(substr($cookievalues,$pos+1)); }
這樣就方便使用了。
在云函數 SCF 中,全局變量目前有個坑,就是上次訪問獲取的全局變量在這次并不會清空,所以本次訪問的時候,上次提交的值可能還在全局變量中,這個情況不管是 php 固有的超全局還是自己定義的,都有這個情況,所以使用前注意 unset。
用戶提交過來的數據,除了 GET、POST、COOKIE,還有一種比較重要的就是路徑了,比如這樣一個 url: https://cache.yisu.com/upload/information/20210523/355/727923.jpg?foo=bar,在 API 網關中,/path/file.jpg 會被放到 $event['path']
中,但注意,如果通過 API 網關默認 url 訪問,里面會含有 /functionname ,注意去除(以下代碼將路徑里起始的 '/' 也去除了):
$function_name = $context['function_name']; $host_name = $event['headers']['host']; $serviceId = $event['requestContext']['serviceId']; if ( $serviceId === substr($host_name,0,strlen($serviceId)) ) { // using long url of API gateway // 使用API網關長鏈接時 $path = substr($event['path'], strlen('/' . $function_name . '/')); } else { // using custom domain // 使用自定義域名時 $path = substr($event['path'], strlen($event['requestContext']['path']=='/'?'/':$event['requestContext']['path'].'/')); }
取得用戶提交的信息后,就可以自己處理了,過程不詳談,只是注意:
SCF 是只讀的,只有
/tmp/
目錄可讀寫,這個 tmp 目錄并發實例間互不相通,實例結束后銷毀。
處理完后,就要輸出給瀏覽器了,注意,因為跟瀏覽器對話的是 API 網關,
在代碼中直接 echo 的話,只會顯示在運行日志中,瀏覽器完全看不到,
所以
我們需要在
main\_handler
中把需要顯示的東西 return 給 API 網關。
這時,如果要返回一個網頁,那 API 網關要勾選「集成響應」,SCF 這邊要返回一個特定結構的數組,這樣瀏覽器才會正常顯示,不然瀏覽器就會只看到一堆字符串。
return [ 'isBase64Encoded' => false, 'statusCode' => 200, 'headers' => [ 'Content-Type' => 'text/html' ], 'body' => $html ];
其中 body 就是我們要返回的網頁內容,是個字符串;
headers 是給瀏覽器辨認的,Location 或 Set-Cookie 要放在這里面;
statusCode 是狀態碼,可以在 Location 時為 302,也可以在某些時候 404;
isBase64Encoded 是 API 網關用的,告訴它,body 里面是否 base64 加密。
這樣返回,瀏覽器就會顯示一個 HTML 網頁了。
但有些時候,我們想給一個文件給用戶下載,這時候,就要用到 isBase64Encoded 了:
$image_data = fread(fopen('logo.png', 'r'), filesize('logo.png')); return [ 'isBase64Encoded' => true, 'statusCode' => 200, 'headers' => [ 'Content-Type' => 'image/png' ], 'body' => base64_encode($image_data) ];
這樣瀏覽器會直接得到一個 png 文件,有些瀏覽器彈出下載,有些自己就打開了。
上面代碼已經提交到云函數 SCF 模板庫:https://github.com/tencentyun/scf-demo-repo/tree/master/Php7.2-QRcodewithLogo ,不吝賜教!
看完上述內容,你們掌握云函數SCF中PHP的入門坑有哪些的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。