HTML form submit same name in php, nodejs, golang
on 2020-10-24
一直以來大部分時間都在用 PHP 開發
所以也用 PHP 來處理 HTML Form
所以都下意識地認為 <input type="checkbox" name="game[]" value="FGO">
這樣的 name="game[]"
的處理方式是正規的處理 HTML Form 的多選的方式
也疑惑為何大多的 HTML Form 的教學甚至 MDN 都沒有提到這件事
就在某一天我在檢視到同事寫的 code 時
發現同事用 JavaScript 處理
硬爬出來自己組字串送出去
我才想起這令人感到恐懼的事情
因為公司同事是寫 golang 的專門, 就算前端不熟
應該也不至於連這樣概念都沒有就用硬爬的方式處理
所以再調整的同時也跟同事確認後
我也真正的直視這問題
到底要怎麼處理表單中多選的資料?
PHP 寫久的人大多都知道要用上面列出的方法
name="game[]"
就是 game
+ []
但是當我認真地尋找關於這個問題時
意外地發現了一篇 stackoverflow 的問答
Several Checkboxes sharing the same name
其實 W3C 根本沒有管你 name="" 重複要如何處理
以下是 PHP, nodejs, golang 的原生方式來測試的結果
PHP
以下問答有提供了 PHP doc 說明 PHP 如何處理多選
在 name 後面添加 []
即可處理把相同的 name 組成 Array
沒有加的話是會取最後一個
POST & GET 都是如此處理
example:
<input type="checkbox" name="game[]" value="FGO" />
<input type="checkbox" name="game[]" value="GirlsFrontline" />
<?php
$_GET['game'];
$_POST['game'];
nodejs
GET 和 POST 用的方式不一樣
基本上都會用到 querystring
module
querystring
module 主要都在處理 querystring 相關的功能
主要靠它 parse querystring format(ex: key=calue&key2=value2)
所以 nodejs 會自動把同樣的 name 併在一起組成 array
GET
會需要用 url
module
url
module 主要是要拿掉 GET 的 url 的 querystring 再丟給 querystring
處理
example:
<input type="checkbox" name="game" value="FGO" />
<input type="checkbox" name="game" value="GirlsFrontline" />
const url = require("url");
const querystring = require("querystring");
const thisUrl = new URL(req.url, "http://" + req.headers.host);
const query = new URLSearchParams(thisUrl.search).toString(); // 這一段是要把 `?key=calue&key2=value2` => `key=calue&key2=value2`
querystring.parse(query)["game"];
POST
把接進來的 body 組起來再使用 querystring
parse
example:
var formData = "";
req.on("data", function (data) {
formData += data;
});
req.on("end", function () {
console.log(querystring.parse(formData)["game"]);
});
URL | Node.js v15.0.1 Documentation
Query string | Node.js v15.0.1 Documentation
golang
import http
就可以處理 GET 和 POST 的情況
大致上的處理方式和行為和 nodejs 一樣(只差在語言的寫法不一樣)
也是會自動把同樣的 name 併在一起
組成 slice
GET
request struct 裡面有 URL 有 function Query
可以拿到所有的 querystring
example:
<input type="checkbox" name="game" value="FGO" />
<input type="checkbox" name="game" value="GirlsFrontline" />
package main
import (
"fmt"
"net/http"
)
func getHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.URL.Query()["game"])
}
func main() {
http.HandleFunc("/get", getHandler)
}
POST
request 有一個 parseForm
的 function 可以抓取 HTTP POST
, PUT
, and PATCH
的 body
example:
package main
import (
"fmt"
"net/http"
)
func postHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
fmt.Println(r.Form["game"])
}
func main() {
http.HandleFunc("/post", postHandler)
}
最後總結
只有 PHP 要在相同的 name 後面添加 []
才可以在 PHP 端收到的 name 併在一起
nodejs 和 golang 都只要是 name 一樣就可以了
針對這三種語言都有寫了 demo code
只要三種語言的環境裝好
都可以直接起 local server 來試驗看看
php - 載入文字轉成圖片
on 2020-05-14
需求
讀取一段文字後
可以決定字型
最後要轉成圖片
使用的工具
-
php7.2
-
freetype
提前說明需要用到 GD(這通常預設就啟動了)
freetype 通常會需要另外安裝
如何先檢查有沒有 GD 和 freetype
先用 phpinfo 檢查即可
-> % php -a
Interactive shell
php >
之後再打
echo phpinfo();
就會 output 資訊了
在搜尋 gd
gd
GD Support => enabled
GD Version => bundled (2.1.0 compatible)
GIF Read Support => enabled
GIF Create Support => enabled
JPEG Support => enabled
libJPEG Version => 9 compatible
PNG Support => enabled
libPNG Version => 1.6.32
WBMP Support => enabled
XBM Support => enabled
有安裝過 freetype 的話
就會一起顯示 FreeType Support
gd
GD Support => enabled
GD Version => bundled (2.1.0 compatible)
FreeType Support => enabled
FreeType Linkage => with freetype
FreeType Version => 2.10.1
GIF Read Support => enabled
GIF Create Support => enabled
JPEG Support => enabled
libJPEG Version => 9 compatible
PNG Support => enabled
libPNG Version => 1.6.37
WBMP Support => enabled
XBM Support => enabled
WebP Support => enabled
目前環境是 Mac OSX 10.14.6
安裝 freetype 的方式大致上有三種
-
重新編譯 PHP
-
brew 安裝新的 PHP
因為剛好之前是用 Mac 自帶的 PHP 來用(PHP 7.1.23)
就順便用 brew 安裝 PHP 7.2 也順便改成用 brew 安裝的 PHP 7.2 當之後本地端的開發
brew 安裝完後其實就也一起裝好 freetype 了
這裡額外提一下自己其實有部分的開發都用 docker 開發了, 因為 PHP 版本不一(升級成本太高了, 且 PHP 不是開發主力) 所以就用 docker 封裝管理不同的服務
所以得注意一下 PHP 語法和 extension 的支援
Code
先使用 imagettftext
需要再使用 imagepng
來輸出成圖片
以下為簡單的範例
// 先建立一個畫布
$im = imagecreatetruecolor(1400, 320);
// 建立顏色
$white = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im, 0, 0, 0);
// 建立一個塗滿背景的區域
imagefilledrectangle($im, 0, 0, 1400, 320, $white);
// 文字
$text = '中文繁體 text';
// 字型
$font = 'NotoSansTC-Regular.otf';
// 輸出的檔案
$file = 'font.png';
// 添加文字到圖片中
imagettftext($im, 112, 0, 10, 160, $black, $font, $text);
// 輸出成 PNG
imagepng($im, $file, 9);
當然要輸出成其他圖片格式 PHP 也有 imagejpeg
等 function 可以使用