分類
PHP

[PHP]使用file_get_content來進行post request

在 php 程式中, 使用 curl 來進行 web request 是常用的方式, 不過由於在 https://repl.it/ 這個服務中, php webserver 並未安裝 curl, 所以需要改用 file_get_content()這個函數來進行 web request, 然而若為一般的 get request, 直接將網址傳入即可, 但若需要進行 post request 要如何操作呢?

這時會用到一個 http context options:

https://www.php.net/manual/en/context.http.php

範例程式如下:

<?php

$postdata = http_build_query(
    array(
        'var1' => 'some content',
        'var2' => 'doh'
    )
);

$opts = array('http' =>
    array(
        'method'  => 'POST',
        'header'  => 'Content-Type: application/x-www-form-urlencoded',
        'content' => $postdata
    )
);

$context  = stream_context_create($opts);

$result = file_get_contents('http://example.com/submit.php', false, $context);

?>

也就是利用了 http context options 來組合出要傳遞的參數. 如此一來便能很快速地應用在僅有 file_get_contents() 環境而沒有 curl 的 php webserver 環境來進行 post request.

參考資料:

https://stackoverflow.com/questions/2445276/how-to-post-data-in-php-using-file-get-contents

https://www.php.net/manual/en/context.http.php

 

分類
PHP

[PHP]array_filter with preg_match問題

在使用 array_filter 時, 由於原本的內容過濾條件需要用 regular expression 表示, 來將滿足條件的內容整理出來. 不料發現了問題.

問題的來源是在 array_filter 中, 若使用了 anonymous function , 在 anonymous function 中的變數 scope 是拿不到外部已設定好的變數. 也就是若要取得用變數傳入的值, 需要使用 global 指示詞.

$patternstr = "/.*-20200902-.*/";
$myarray4 = array_filter($myarray, function($v){
  global $patternstr;
  return preg_match($patternstr, $v);
});

如此一來才能順利使用動態的變數字串做為 array_filter 中使用 preg_match 的 pattern 參數. 完整測試程式碼請參考:

https://repl.it/@timhuangt/arrayFilter

分類
好用軟體

好用方便的虛擬主機管理器 – CyberPanel

這個管理工具, 是類似 cPanel、Plesk 這類的 hosting 服務的管理工具, 若是搭配 OpenLiteSpeed 版本的 web service 是完全免費的, 十分佛心.

而搭配 LiteSpeed 版本的 web service 的 CyberPanel Ent. 版, 在 1 domain 下, 2GB Ram 下也是每個月 0元, 可以參考價格說明:

https://cyberpanel.net/cyberpanel-enterprise/

而 OpenLiteSpeed 與 LiteSpeed Ent 版本有什麼差異, 可以參考這裡:

https://www.litespeedtech.com/products/litespeed-web-server/editions

安裝支援的系統有 Centos 7.x, Centos 8.x, Ubuntu 18.04, Ubuntu 20.04, 另外需要的條件有: Python 2.7, 1024MB or above Ram, 10GB Disk Space. 可以參考安裝說明:

https://cyberpanel.net/docs/installing-cyberpanel/

安裝完成後, 應用服務包含了 php (多版本), web, mysql, mail, ftp, dns, ssl 等, 十分方便, 另外管理介面使用 8090 port , 若希望管理介面也能用 let’s encrypt ssl 可以參考這篇的設定方式:

https://cyberpanel.net/docs/2-cyberpanel-on-ssl/

簡單說明, 也就是建立一個 website, 域名為你想用來管理的域名, 然後再到管理介面左側選單的 SSL, Hostname SSL, 選擇你想用的 website 域名後, 再按下 Issue SSL 即可.

他的 email service web 介面使用了 rainloop 也十分方便, 另外也支援了 DKIM 功能, 一樣能透過 SSL/TLS 加密 email 與使用 smtp / pop3 / imap 等方式來存取.

這個工具十分方便, 有在管理多虛擬主機的朋友們可以參考.

分類
PHP

php上實作301 Redirect指示方式

在 php 中若需要重導客戶端, 可以使用 302 重導:

header("Location: http://newlocation");

在不指定 response status 時, 上述內容會使用 302 重導.

若需要使用 301 重導, 可以使用如下程式:

1. 先宣告重導指示, 再進行重導:

header("HTTP/1.1 301 Moved Permanently");
header("Location: http://newlocation");

2. 直接使用 header 中的 response status 參數:

header("Location: http://newlocation", TRUE, 301);

以上兩種方式皆可以重導客戶端至指定目標, 並且以 301 Moved Permanently 方式指示.

繼續閱讀:
https://blog.longwin.com.tw/2015/09/php-301-302-redirect-header-2015/
https://stackoverflow.com/questions/7324645/php-header-redirect-301-what-are-the-implications
https://www.php.net/manual/en/function.header.php

分類
PHP

解決停用TLS1.0加密協議更新CURL問題

今天在解一個已停用 TLS 1.0 加密通訊協定問題時, 發現舊的 web server 上的 php curl 無法正常連線, 在 command line 下使用 curl https://xxx.xxx 時, 也會出現:

curl: (35) TCP connection reset by peer

研判為 curl 的原因造成, 由於需要使用 php 中的 curl_xxxx 系列指令與其他 server 的 api 溝通, 所以必須更新對應的模組來解決, 指令如下:

yum update nss curl openssl

更新完成後, 重起 apache 即完成正常呼叫其他 server api 停用 TLS1.0 的加密通訊協議問題.

參考資料:
https://stackoverflow.com/questions/30145089/tls-1-2-not-working-in-curl

分類
Database

MongoDB使用PHP查找特定欄位是否存在

由於 MongoDB 是一種 schema-free 的資料庫, 使用 Document 為基礎的存放方式, 所以若是想要查找特定欄位是否存在的語法就很重要了, 先來看看官方的資料:

https://docs.mongodb.com/manual/reference/operator/query/exists/

語法是使用 $exists 的方式來判定特定欄位是否存在, 若要轉為 php 語法的話, 可以使用如下:

$cursor= $collection->find([ "field1" => [ '$exists' => false ] ]);

來列出在 collection 中 field1 不存在的資料, 這對於使用特定欄位做為處理資料或作業資料來說, 可以方便地判斷, 也不用預先開好欄位, 很方便實用的一個用法.

分類
PHP

CentOS中apache與php寫入權限與SELinux設定

由於 CentOS 有 SELinux 的權限設限, 所以相對一些安全層級也都比較高, 最近有個需要用 php 寫入檔案(或是上傳檔案的應用), 原本的 php 在預設狀況下, 就會對 /tmp 有寫入的權限(預設是會在 /tmp/systemd-private-xxxxxx 下的私有 /tmp), 所以上傳時沒有問題, 但使用 move_uploaded_file() 至目的目錄時, 會有寫入的權限問題.

方式如下:

Method A
1. 要寫入需要有對應的權限, 建議方式是將要寫入的目錄給予 apache 執行用戶的擁有者, 如 CentOS 配 apache 時, user 為 apache

chown -R apache /var/www/mysite1/upload

2. 此時只需要給予對應目錄 755 的權限即可(通常預設也是這個).

chmod -R 755 /var/www/mysite1/upload

Method B (不建議)
1. 直接給予該目錄 global write 的權限, 777 即可, 不過會有安全性的考量

chmod -R 777 /var/www/mysite1/upload

完成之後, 若仍無法寫入, 則是因為 SELinux 的設限, 所以即使完成了上面的設定也無法寫入, 此時要再進一步設定 SELinux, 方式如下:

sudo chcon -t httpd_sys_rw_content_t /var/www/mysite1/upload -R

原因為預設的 webservice 能擁有的權限角色為 httpd_sys_content_t , 是無法寫入檔案的, 所以需要再進一步設定 SELinux 才行.

參考資料:
https://blog.lysender.com/2015/07/centos-7-selinux-php-apache-cannot-writeaccess-file-no-matter-what/

另外寫得很仔細的 SELinux 資料可以參考:
https://www.digitalocean.com/community/tutorials/an-introduction-to-selinux-on-centos-7-part-1-basic-concepts
https://www.digitalocean.com/community/tutorials/an-introduction-to-selinux-on-centos-7-part-2-files-and-processes
https://www.digitalocean.com/community/tutorials/an-introduction-to-selinux-on-centos-7-part-3-users

分類
PHP

PHP好用線上測試功能

這個線上的沙箱測試, 可以讓你在不同的 PHP 版本間進行 PHP程式的測試, 有時候需要一小段程式來測試與驗證時, 可以利用這樣的工具來達成, 網址:

http://sandbox.onlinephpfunctions.com/

不僅可以測試 php 程式碼, 還可以進行儲存與分享, 是在 php 程式開發時, 可以快速撰寫小程式的好用工具, 很方便快速, 請多多利用.

例如以 php 網站上的一個 callback function範例:

// Our closure
$double = function($a) {
    return $a * 2;
};

// This is our range of numbers
$numbers = range(1, 5);

// Use the closure as a callback here to
// double the size of each element in our
// range
$new_numbers = array_map($double, $numbers);

print implode(' ', $new_numbers);

放在該網站執行並存檔分享連結為:

http://sandbox.onlinephpfunctions.com/code/c9a175417fddfc1ed0aef4a48feb5de384c49e3d

真的又快又方便!

分類
程式技術

使用PHP上傳圖片至Azure Storage供圖檔應用

使用 PHP 將圖檔上傳至 Microsoft Azure 雲端空間供圖檔應用, 有以下幾個步驟:

1. 建立 Azure 的 Storage Account , 並取得 key 與建立 container (也可以使用程式建立)

2. 安裝 Azure PHP Client: http://azure.microsoft.com/en-us/documentation/articles/storage-php-how-to-use-blobs/

2-1. 先安裝 Git
2-2. 依說明建立 composer.json 與下載 composer.phar (http://getcomposer.org/composer.phar), 並進行安裝: php composer.phar install
2-3. 完成程式下載

3. 在 php 程式碼中引入對應程式碼, 以上傳圖檔為例, 程式碼如下:

require_once 'vendor/autoload.php';
use WindowsAzure\Common\ServicesBuilder;
use WindowsAzure\Common\ServiceException;
use WindowsAzure\Blob\Models\CreateBlobOptions;

$connectionString = "DefaultEndpointsProtocol=https;AccountName=[storage account name];AccountKey=[storage access key]";

$blobRestProxy = ServicesBuilder::getInstance()->createBlobService($connectionString);

$content = fopen("myfile.jpg", "r");
$blob_name = "myfile.jpg";
$createBlobOptions = new CreateBlobOptions();
$createBlobOptions->setBlobContentType("image/jpeg");

try {
    //Upload blob
    $blobRestProxy->createBlockBlob("[container name]", $blob_name, $content, $createBlobOptions);
    echo "ok";
    echo "<img src='http://[storage account name].blob.core.windows.net/[container name]/".$blob_name."' />";
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here: 
    // http://msdn.microsoft.com/library/azure/dd179439.aspx
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

其中範例中的程式, 並沒有指定對應 blob 中的 Content-Type, 會使用預設的 application/octet-stream , 其實在網頁使用並無影響, 但若是直接連結會變成是下載的狀況, 比較不適合, 而且也應該是指定為正確的 Content-Type 較佳.

若有需要使用到 php 上傳圖檔至 Azure storage, 可以參考上面做法進行上傳應用.

相關資料:
Put Blob: https://msdn.microsoft.com/library/azure/dd179451.aspx

使用 ASP.NET 版本參考這篇:
http://blogs.msdn.com/b/ericsk/archive/2013/12/18/php-on-windows-azure-windows-azure-blob-storage.aspx

分類
PHP

好用工具Encode Explorer

今天在協助朋友解決一個在 linux apache 下的 php 程式對中文檔名檔案存取的問題, 在思考在 linux 下的 file system 對中文檔名存放的編碼時, 想說直接找個工具來用比較快. 因為其實不需要真的去檢查看 file system 上中文檔名存放的編碼, 只需要找個 php 的 file explorer 來進行就可以了, 找出對應的編碼即可. 實際上, 之後的程式也是透過 php 存取, 所以用 php 的 file explorer 檢查是最方便不過了.

找到這個好用的工具, 短小精幹, 一支主程式, 就是這麼方便: Encode Explorer – http://encode-explorer.siineiolekala.net/

可以先試看看該網站的 demo: http://encode-explorer.siineiolekala.net/explorer/index.php

一支程式就可以做 file exploer 功能, 所以利用這樣的方式來檢查看中文檔名是否正常, 該程式預設是使用 utf-8 的, 不過朋友的虛擬主機上是 big5 的中文編碼, 所以在 Encode Exploer 下看到亂碼的中文檔名, 利用瀏覽器的編碼改為 big5 就看得到該中文檔名了, 這下就明白朋友的虛擬主機上的中文檔名是走 big5, 對後續在應用 timthumb.php 縮圖無法正確取得本地中文檔名的問題就解決了.

若網友們有碰到這樣的問題, 也可以試著用這套工具來檢查看看. 當然, 若是需要找個方便好用的 php file exploer, 這套工具也是十分方便好用呢!