category: php

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 如何處理多選

PHP Multiple Checkbox Array

在 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)
}

http - parseForm

最後總結

只有 PHP 要在相同的 name 後面添加 [] 才可以在 PHP 端收到的 name 併在一起

nodejs 和 golang 都只要是 name 一樣就可以了

針對這三種語言都有寫了 demo code

只要三種語言的環境裝好

都可以直接起 local server 來試驗看看

html_form_multiple_name

Read more

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 的方式大致上有三種

  1. 重新編譯 PHP

  2. brew 安裝新的 PHP

  3. 用別人寫的安裝 PHP 的指令

因為剛好之前是用 Mac 自帶的 PHP 來用(PHP 7.1.23)

就順便用 brew 安裝 PHP 7.2 也順便改成用 brew 安裝的 PHP 7.2 當之後本地端的開發

brew 安裝完後其實就也一起裝好 freetype 了

這裡額外提一下自己其實有部分的開發都用 docker 開發了, 因為 PHP 版本不一(升級成本太高了, 且 PHP 不是開發主力) 所以就用 docker 封裝管理不同的服務

所以得注意一下 PHP 語法和 extension 的支援

Refer - macos缺少freetype終極解決方案

Refer - Mac缺少freetype解决方案

Code

先使用 imagettftext

Refer

需要再使用 imagepng 來輸出成圖片

Refer

以下為簡單的範例


// 先建立一個畫布
$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 可以使用

Read more