分類:PHP

PHP將boolean值轉字串

如果有需要將 boolean 的值轉成字串,好方便使用如 in_array() 來判斷的話,可以使用下列方式

$a = true;
$b = false;

$array = [];

$array[] = $a ? 'true' : 'false';
$array[] = $b ? 'true' : 'false';

print_r($array);

結果:

Array ( [0] => true [1] => false )

簡易開發API範例並測試

以下是 Server API 端的程式碼:

$verb = $_SERVER['REQUEST_METHOD'];

if($verb == 'GET')
{
	if(isset($_GET['filename']))
	{
		$file_content = file_get_contents($_GET['filename']);
		echo $file_content;
	}
	else
	{
		die('ERROR: REQUIRED PARAMETERS NOT GIVEN!');
	}
}
elseif($verb == 'POST')
{
	if(isset($_POST['filename']) and isset($_POST['content']))
	{
		file_put_contents($_POST['filename'], $_POST['content']);
	}
	else
	{
		die('ERROR: REQUIRED PARAMETERS NOT GIVEN!');		
	}
}
elseif($verb == 'DELETE')
{
	parse_str(file_get_contents('php://input'), $_DELETE);
	if(isset($_DELETE['file']))
	{
		if(file_exists($_DELETE['file']))
		{
			unlink($_DELETE['file']);
		}
	}
	else
	{
		die('ERROR: REQUIRED PARAMETERS NOT GIVEN!');
	}
}

然後我們可以透過 cURL 或 Chrome 的擴充功能 Advanced REST client 來測試上面的 API 程式。
2017-07-21 10-28-03 的螢幕擷圖

如何自訂 HTTP header 的值並取值

HTTP 超文本傳輸協定區分 header 和 body 兩個部份,我們可以使用下列方式單獨取出 header 來查看

ben@ben-UX305CA:~$ curl --head https://jsonplaceholder.typicode.com/posts/1
HTTP/1.1 200 OK
Date: Fri, 21 Jul 2017 02:09:10 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 292
Connection: keep-alive
Set-Cookie: __cfduid=d202b5717ee9bfe89c339aa98c18de2141500602950; expires=Sat, 21-Jul-18 02:09:10 GMT; path=/; domain=.typicode.com; HttpOnly
X-Powered-By: Express
Vary: Origin, Accept-Encoding
Access-Control-Allow-Credentials: true
Cache-Control: public, max-age=14400
Pragma: no-cache
Expires: Fri, 21 Jul 2017 06:09:10 GMT
X-Content-Type-Options: nosniff
Etag: W/"124-yiKdLzqO5gfBrJFrcdJ8Yq0LGnU"
Via: 1.1 vegur
CF-Cache-Status: HIT
Server: cloudflare-nginx
CF-RAY: 381a9dd9de540d73-SJC

如果我們自己開發 API 時,但又希望只有擁有合法的 API KEY 的使用者才能使用該 API,我們可以自訂 header 參數,把 API KEY 加到 header 裡面。

以下是 client 端的程式碼:

$url = 'http://172.17.0.11/apikey/';
// $query = urlencode('where={"steps":9243}');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt(
    $ch, 
    CURLOPT_HTTPHEADER,
    array(
        'X-Parse-Application-Id: myApplicationID',
        'X-Parse-REST-API-Key: myRestAPIKey',
        'Content-Type: application/json'
    )
);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch);

echo $result;

再來我們可以在該 API 頁面先做簡單測試,看可不可以取得自訂的 header,因為 apache 版本的關係,建議使用方法1 比較方便。

以下是 Server API 端的程式碼:

方法1:

$header = apache_request_headers();
echo '<pre>';
print_r($header);
echo '</pre>';
die();

方法1 結果:

Array
(
    [Host] => 172.17.0.11
    [Accept] => */*
    [X-Parse-Application-Id] => myApplicationID
    [X-Parse-REST-API-Key] => myRestAPIKey
    [Content-Type] => application/json
)

方法2:

echo '<pre>';
print_r($_SERVER);
echo '</pre>';
die();

方法2 結果:(注意-變成_,且前面自動加入HTTP)

Array
(
    [HTTP_HOST] => 172.17.0.11
    [HTTP_ACCEPT] => */*
    [HTTP_X_PARSE_APPLICATION_ID] => myApplicationID
    [HTTP_X_PARSE_REST_API_KEY] => myRestAPIKey
    [CONTENT_TYPE] => application/json
    [PATH] => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    [SERVER_SIGNATURE] => 
Apache/2.2.15 (CentOS) Server at 172.17.0.11 Port 80


    [SERVER_SOFTWARE] => Apache/2.2.15 (CentOS)
    [SERVER_NAME] => 172.17.0.11
    [SERVER_ADDR] => 172.17.0.11
    [SERVER_PORT] => 80
    [REMOTE_ADDR] => 172.17.0.11
    [DOCUMENT_ROOT] => /var/www/html
    [SERVER_ADMIN] => root@localhost
    [SCRIPT_FILENAME] => /var/www/html/apikey/index.php
    [REMOTE_PORT] => 45894
    [GATEWAY_INTERFACE] => CGI/1.1
    [SERVER_PROTOCOL] => HTTP/1.1
    [REQUEST_METHOD] => GET
    [QUERY_STRING] => 
    [REQUEST_URI] => /apikey/
    [SCRIPT_NAME] => /apikey/index.php
    [PHP_SELF] => /apikey/index.php
    [REQUEST_TIME_FLOAT] => 1500603476.817
    [REQUEST_TIME] => 1500603476
)

一旦可以順利取得值後,我們就可以用來判斷是否有權限來執行該 API,甚至可以利用資料庫來增加 API KEY 的使用期限,一旦過期就無法使用等功能。

簡介cURL綜合傳輸工具

cURL是一個利用URL語法在命令列下工作的檔案傳輸工具,1997年首次發行。它支援檔案上傳和下載,所以是綜合傳輸工具,但按傳統,習慣稱cURL為下載工具。cURL還包含了用於程式開發的libcurl。
cURL支援的通訊協定有FTP、FTPS、HTTP、HTTPS、TFTP、SFTP、Gopher、SCP、Telnet、DICT、FILE、LDAP、LDAPS、IMAP、POP3、SMTP和RTSP。
libcurl支援的平台有Solaris、NetBSD、FreeBSD、OpenBSD、Darwin、HP-UX、IRIX、AIX、Tru64、Linux、UnixWare、HURD、Windows、Symbian、Amiga、OS/2、BeOS、Mac OS X、Ultrix、QNX、BlackBerry Tablet OS、OpenVMS、RISC OS、Novell NetWare、DOS等。
來源:https://zh.wikipedia.org/wiki/CURL

另外我們可以使用 JSONPlaceholder 工具網站來測試 REST API
Fake Online REST API for Testing and Prototyping
https://jsonplaceholder.typicode.com/

取得所有資料

curl https://jsonplaceholder.typicode.com/posts

取得一筆資料

curl https://jsonplaceholder.typicode.com/posts/1

取得一筆資料(含header部份)

curl -i https://jsonplaceholder.typicode.com/posts/1

只取header部份

curl --head https://jsonplaceholder.typicode.com/posts/1

只取header部份

curl -I https://jsonplaceholder.typicode.com/posts/1

取得資料並儲存到 test.txt

curl -o test.txt https://jsonplaceholder.typicode.com/posts/3

下載檔案(檔名為參數 3)

curl -O https://jsonplaceholder.typicode.com/posts/3

也可以下載其它檔案(如圖檔)

curl -O http://i.imgur.com/QRlAg0b.png

使用 REST API POST 資料

curl --data "title=Hello&body=Hello World" https://jsonplaceholder.typicode.com/posts

使用 REST API PUT 修改資料(每一個欄位 -d key=value)

curl -X PUT -d title=Hello https://jsonplaceholder.typicode.com/posts/3

使用 REST API DELETE 刪除一筆資料

curl -X DELETE https://jsonplaceholder.typicode.com/posts/3

使用帳號密碼登入有保護的網站位置並取得資料

curl -u test:1234 http://172.17.0.11/lock

有些網站具有跳轉,如下列會返回301或302,無法取得真正檔案資料

curl http://google.com

加上參數 -L 會跟隨跳轉,取得真正位置的檔案資料

curl -L http://google.com

使用 cURL 來登入 FTP 並上傳一個檔案

curl -u test@abc.com:1234 -T hello.txt ftp://ftp.abc.com

使用 cURL 來登入 FTP 並下載一個檔案

curl -u test@abc.com:1234 -O ftp://ftp.abc.com/hello.txt

PHP中斷程式碼並查看變數

如果是使用傳統方式開發程式,沒有抓 bug 套件可隨時中斷查看,可以在要中斷的程式中加入中斷的程式碼


$a = array('a','b','c');
var_dump($a);
die();
echo 'hi';

結果:

array(3) { [0]=> string(1) “a" [1]=> string(1) “b" [2]=> string(1) “c" }


$a = array('a','b','c');
echo '<pre>';
print_r($a);
echo '</pre>';
die();
echo 'hi';

結果:

Array
(
    [0] => a
    [1] => b
    [2] => c
)

以上兩種方式都不會執行最後一行的 echo ‘hi'; 程式碼,但陣列的顯示方式有所不同,可視情況選擇不同的顯示方式。

PHP getimagesize(): php_network_getaddresses 錯誤訊息

使用 Docker 開發時,在商品內頁出現錯誤訊息
這是因為 Container 中的 Server 無法辨識程式內所設定的網域名稱

<h4>A PHP Error was encountered</h4>

<p>Severity: Warning</p>
<p>Message:  getimagesize(): php_network_getaddresses: getaddrinfo failed: Name or service not known</p>
<p>Filename: shop/shopctrl.php</p>
<p>Line Number: 1271</p>

<h4>A PHP Error was encountered</h4>

<p>Severity: Warning</p>
<p>Message:  getimagesize(http://trprj.fyvm.docker/trupl/shop/product_cover_148410523073244600.jpg): failed to open stream: php_network_getaddresses: getaddrinfo failed: Name or service not known</p>
<p>Filename: shop/shopctrl.php</p>
<p>Line Number: 1271</p>

進入 Docker 中,修改 /etc/hosts,加入以下即可

127.0.0.1   trprj.fyvm.docker

注意!如果對 container 操作 stop 再 restart 後,container 裡的 /etc/hosts 檔案將自動回復,將會再度出現錯誤訊息