2023年1月17日
Codeigniter系統異常登出問題 "Session Error" 原因與解決方法
2022年12月1日
PHP常用的日期時間格式整理
作者: Fred F.M. Wang (FW知識瑣記) 日期: 2022-12-1
以下為筆者整理常用的PHP擷取日期時間的格式。
PHP語法 :
$data = date("<格式>", strtotime($date_string))
格式 :
日(每月幾號,當月的第幾天)
d : 01~31
j : 1~31
S : 每月第幾個日期, 與j可共用 st, nd, rd, th…
ex: jS : 1st, 2nd, 3rd, 4th….
星期幾
w : 0~6 (0 for Sunday)
N : 1~7 (7 for Sunday)
D : Mon~Sun
l (小寫L) : Sunday~Saturday
一年的第幾天
z : 0~365 (0: 第一天)
一年的第幾周
W : 從該年第一個星期一算起
月份
m : 01~12
n : 1~12
M : Jan~Dec
F : January~December
該月份共幾天(最後一天的日期) *****
t : 28~31, date(“Y-m-t”) 本月最後一天
年
Y : ex. 1999
y : ex. 99
是否為閏年
L : 1閏年 0非閏年
時
H : 24小時制00~23
G : 24小時制0~23
h : 12小時制01~12
g : 12小時制1~12
A: AM or PM
a : am or pm
分
i : 00~59
秒
s : 00~59
毫秒
v: ex:645
2022年11月1日
Codeigniter Word套表應用的開發步驟
作者: Fred F.M. Wang (FW知識瑣記) 日期:2022-11-1
PHP的Excel的套表應用開發程序比較單純,直接可以用程式將資料寫入樣板檔的相關儲存格,但是Word的套表就必較複雜,如下圖右邊為Excel套表的開發步驟,左邊是Word套表的開發步驟。
準備 :
Codeigniter使用PHPWord版本是CI_PHPWord,程式庫來源為https://github.com/rifqisucahyo/CI_PHPWord
依連結中的說明,將各檔案放到您 Codeigniter專案的資料夾中。
然後將phpword\template.php檔案的這行註釋掉:$replace = utf8_encode($replace);
樣板製作與程式設計步驟 :
Step 1 將設計好的Word表單檔(.docx檔)使用MS Word轉存成XML檔。
Step 2 使用文字編輯器編輯XML, 找到檔案中放資料位置,插入變數,格式為 ${變數名稱}
Step 3 再將編輯完成的XML檔使用MS Word轉存成Word表單檔(.docx檔),再將這個帶有變數名稱的樣板檔放在Server上成為正式的樣板。
Step 4 撰寫程式,將資料寫入樣板文件的變數中,並儲存成表單文件檔。
注意 :
1. 如果要變更樣板內容,不能直接編輯Step 3的樣板檔(.docx檔),必須修改Step 1產生的XML檔,再進行Step 2至Step 4。
2. 內容中如果有&符號會造成轉換後的Word檔無法讀取,因此先將內容的”&”用逗號等符號取代,再寫入。例如 $objPHPWordOut->setValue("desc",str_replace("&",",",$data["description"]));
範例程式 :
// 樣本檔檔案路徑為$templatefile, 例如下面程式
$templatefile = dirname($_SERVER["SCRIPT_FILENAME"]) . "/templates/app1/form_template.docx";
// 要寫出的檔案路徑為$outfilepath, , 例如下面程式
$outfile = "exports/app1/doc_" . date("YmdHis"). ".docx";
$outfilepath = dirname($_SERVER["SCRIPT_FILENAME"]) . "/" .$outfile;
$this->load->library("word");
$PHPWord = $this->word;
$objPHPWordOut = $PHPWord->loadTemplate($templatefile); // 載入樣板檔
// $data是要寫入的資料陣列
$this->write_data_to_word($objPHPWordOut,$data); // 寫入資料
$objPHPWordOut->save($outfilepath); // 儲存至寫出檔案
private function write_data_to_word($objPHPWordOut,$data) {
// 將$data[“id”]的內容取代樣板檔中變數id也就是 $id
$objPHPWordOut->setValue("id",$data["id"]);
…
}
參考來源 : PHPWord中文手冊整理- ITW01
2021年9月2日
如何解決PHP日期2038年的限制?
作者: Fred F.M. Wang (FW知識瑣記) 日期:2021-9-2
以往以PHP寫日期相關程式,習慣用strtotime函式將字串轉換為時間,並用date函式以特定的日期
格式顯示出來。但是最近遇到了2038年後的日期顯示出問題了。如何解決呢?
舊寫法 :
$date = date("Ymd",strtotime("2038-1-19"));
echo "2038-1-19 :" . $date . "<br />";
使用日期(date)函式,結果顯示 2038-1-19 :20380119
$date = date("Ymd",strtotime("2038-1-20"));
echo "2038-1-20 :" . $date . "<br />";
使用日期(date)函式, 結果顯示 2038-1-20 :19700101
由此看到日期(date)函式2038年1月20日之後的日期都無法正確顯示了
同樣要顯示日期增減也是會發生同樣的問題,當日期增加超過2038-1-20日,就無法顯示出來。
$this_date = Date("Ymd");
echo "today:" . $this_date . "<br />"; // 顯示 today:20210831
$date = date("Ymd",strtotime("+5985 days", strtotime($this_date)));
echo "add 5985 days:" . $date . "<br />"; // 顯示 add 5985 days:20380119
$date = date("Ymd",strtotime("+5986 days", strtotime($this_date)));
echo "add 5986 days:" . $date . "<br />"; // 顯示 add 5986 days:19700101
怎麼解決2038年的限制呢?
您必須改用DateTime函式來取得日期(將日期字串轉成日期),並用format函式以特定的日期格式
顯示出來
$date = new DateTime($this_date);
日期的增加則使用add函式
$date->add(new DateInterval("P6000D")); // P開頭代表日期,6000D 代表 6000 天
echo "add 6000 days:" . $date->format("Ymd"); // add 6000 days:20380203
2020年12月8日
PHP解決錯誤訊息 "preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead"的方法
作者: Fred F.M. Wang (FW知識瑣記) 日期: 2020/12/8
Codeigniter 搭配PHP 5.5版時,前端程式(View)送出(Submit)表單資料到後台程式(controller)
時發生錯誤訊息 core\Security.php : "preg_replace(): The /e modifier is deprecated, use
preg_replace_callback instead"
錯誤的程式 : \system\core\Security.php
錯誤的行: line 152, 153
$str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str);
return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str);
原因 : /e 修飾符在PHP 5.5中已經棄用, 要用preg_replace_callback()取代
查到PHP官網的解釋
/e修飾符在PHP 5.5已不推薦使用會產生Warning, 在PHP 7已經移除, 因為它很容易產生安漏
洞,可以使用preg_replace_callback()取代
官網說明內容如下 (ref : https://www.php.net/manual/zh/reference.pcre.pattern.modifiers.php)
因此Codeigniter系統的 \system\core\Security.php程式中line 152, 153
$str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str);
return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str);
要改寫成
$str = preg_replace_callback('~&#x(0*[0-9a-f]{2,5})~i', function($m){ return chr(hexdec($m[1])); }, $str);
return preg_replace_callback('~&#([0-9]{2,4})', function($m){ return chr(hexdec($m[1])); }, $str);
如此問題就解決了。
2020年9月7日
PHP程式設計: PHP程式如何將圖片放入excel檔案中 Using PHPExcel
作者: Fred F.M. Wang (FW知識瑣記) 日期:20200907
PHP程式中可以使用PHPExcel讀取製作好的Excel樣板,根據條件動態寫入資料,產生新的Excel檔案,用於產生Excel報表檔。
如果要根據不同條件放入不同的簽名圖片檔要怎麼做?
可以參考下面範例 :
// 主程式
$objPHPExcelOut = PHPExcel_IOFactory::load($outfilepath); // $outfilepath寫入的Excel檔案路徑
$PHPExcelWriter = PHPExcel_IOFactory::createWriter($objPHPExcelOut, "Excel2007");
….
<寫入資料>
.....
$row = 30;
$signcol = "E";
$offsetX = 27;
$offsetY = 10;
// 寫入簽名檔
$this->addSignImage($objPHPExcelOut,$signcol,$row,$offsetX,$offsetY);
/* ***** 副程式:寫入簽名檔 ***** */
private function addSignImage($objPHPExcelOut,$column,$row,$offsetX,$offsetY) {
$signimgfile = dirname($_SERVER["SCRIPT_FILENAME"]) . "<圖片來源檔案路徑>";
// <圖片來源檔案路徑與檔名> 例如"/files/shipinf/templates/image_imqsign.png"
$gdImage = imagecreatefrompng($signimgfile);
// 保持PNG圖片背景透明
imagealphablending($gdImage, false); // 關閉 alpha 渲染
imagesavealpha($gdImage, true); // 並設置 alpha 標誌以在保存 PNG 圖像時保存完整的
alpha 通道資訊
$objDrawing = new PHPExcel_Worksheet_MemoryDrawing();
$objDrawing->setName("signimage");
$objDrawing->setDescription("signimage");
$objDrawing->setImageResource($gdImage);
$objDrawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG);
$objDrawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT);
$objDrawing->setCoordinates($column.$row); // 圖片左上角放置在哪個儲存格的位置
$objDrawing->setHeight(390); // 設定圖片高度(寬度會等比例變寬)
$objDrawing->setOffsetX($offsetX); // 向左位移幾個像素
$objDrawing->setOffsetY($offsetY); // 向下位移幾個像素
$objDrawing->setWorksheet($objPHPExcelOut->getActiveSheet());
}
2020年8月20日
[輸入判斷] PHP判斷前端Checkbox欄位是否勾選
作者: Fred F.M. Wang (FW知識瑣記) 日期:20200820
PHP程式接收前台網頁輸入的值,比較容易發生錯誤的是checkbox欄位,不像其他類型的輸入欄位
可以單純用$_POST['<field name >']接收輸入值那麼簡單。
前端的一個checkbox輸入欄,如果沒有勾選,則該表單submit後,後台PHP處理程式無法接收到此欄位的內容,因此判斷checkbox輸入欄是否有勾選,要用
isset($_POST['<field name >'])來判斷,如下面範例:
前端HTML
<form action="getcheckbox.php" method="post">
Only Weekend<input type="checkbox" name="wkend" value="weekendonly">
<input type="submit" value="submit">
</form>
後端PHP
<?php
$wkend = false;
if(isset($_POST['wkend'])) {
$wkend = true;
echo "weekly only checked";
} else {
echo "Not check weekly only";
}
?>
2020年7月31日
PHP二維key-value陣列根據特定欄位內容去除重複資料
PHP一維陣列要移除重複的內容,很簡單只要使用array_unique函式即可
例如 :
$input = array("green", "red", "green", "blue", "red");
$result = array_unique($input);
結果$result內容為array( "green", "red", "blue");
二維的key-value陣列要根據特定欄位內容移除重複,要如何處理?
下面是多維(key-value)陣列 :
items[0][“fieldname1”] = …;
items[0][“fieldname2”] = …;
items[0][“fieldname3”] = …;
items[0][“fieldname4”] = …;
…
items[0][“fieldnamen”] = …;
items[1][“fieldname1”] = …;
items[1][“fieldname2”] = …;
items[1][“fieldname3”] = …;
items[1][“fieldname4”] = …;
…
items[1][“fieldnamen”] = …;
….
要去除上面陣列 fieldname1, fieldname2, fieldname3欄位內容相同的item, 程式如下 :
$new_items = array();
$keys = array();
if(!empty($items)) {
foreach($items as $key => $rec) {
$reckey = array($rec["fieldname1"],$rec["fieldname2"],$rec["fieldname3"]);
if(!in_array($reckey,$keys)) {
$keys[] = $reckey;
$new_items[] = $rec;
}
}
}
$items = $new_items;
2020年7月20日
PHP程式解決記憶體不足的錯誤 "Allowed memory size of ... bytes exhausted"
PHP程式執行時發生下面錯誤
Fatal error: Allowed memory size of ... bytes exhausted (tried to allocate ... bytes) in ….
表示是可用記憶體已耗盡。
可透過兩種方法解決 :
1、修改php.ini
例如 : memory_limit = 128
這種方法需要重啟web服務器。
2、在程式中使用ini_set函數修改設訂選項值
例如 : ini_set ('memory_limit', '128M')
如果一直加大記已體還解決不了問題,那麼可能程式中發生幾種無限耗用資源的情況
1 無窮的迴圈 : 迴圈中持續分配記憶體,例如增加陣列大小
2 無窮的遞迴程式 : 遞迴程式沒有寫好結束的條件。
3 使用了過大的陣列或過多的變數 (註 : 程式中不再用到陣列或變數,可使用unset()或$var = null釋放記憶)
好好檢查程式吧!
2020年6月29日
PHPExcel如何在工作表內放入ㄧ個圖片(背景是透明的PNG檔)
前ㄧ篇文 "PHPExcel 無法儲存寫入內含圖片的Excel檔,問題如何解決?",解決在儲存有Logo圖片的工作表問題後,另一種情況就是除了Logo外,還要加入一張圖片,而且圖片為背景是透明的PNG檔。嘗試後,分享程式如下 :
private function addSignImage($objPHPExcelOut,$column,$row) {
$signimgfile = dirname($_SERVER["SCRIPT_FILENAME"]) . "/資料夾名稱/檔名.png";
$gdImage = imagecreatefrompng($signimgfile);
// 保持PNG圖片背景透明
imagealphablending($gdImage, false); // 關閉alpha渲染
imagesavealpha($gdImage, true); // 設置alpha標誌以在儲存PNG圖像時保存完整的alpha通道資訊
$objDrawing = new PHPExcel_Worksheet_MemoryDrawing();
$objDrawing->setName("signimage");
$objDrawing->setDescription("signimage");
$objDrawing->setImageResource($gdImage);
$objDrawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG);
$objDrawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT);
$objDrawing->setCoordinates($column.$row); // 圖片左上角放置在哪個儲存格的位置
$objDrawing->setHeight(390); // 設定圖片高度(寬度會等比例變寬)
$objDrawing->setOffsetX(288); // 向左位移幾個像素
$objDrawing->setOffsetY(14); // 向下位移幾個像素
$objDrawing->setWorksheet($objPHPExcelOut->getActiveSheet());
}
主程式
$objPHPExcelOut = PHPExcel_IOFactory::load($outfilepath);
$objPHPExcelOut->setActiveSheetIndex(0); // 預設0是指第一個工作表
.....
$col = "D";
$row = 27;
$this->addSignImage($objPHPExcelOut,$col,$row);
2020年5月29日
PHPExcel 無法儲存寫入內含圖片的Excel檔,問題如何解決?
PHPExcel是一個PHP程式中用來存取Excel檔案很好用的程式庫。
我常常用套表的方式產生Excel檔報表,也就是事先建立一個Excel樣板格式檔,將格式調整好,如標題,表格標頭,欄寬欄高,表格框線,列印格式等設定在樣本檔中。然後,在PHP程式中,複製此樣本檔產生目的檔案,在將資料寫入目的檔案內。
最近發現的問題是,如果樣版格式內有圖片,例如公司Logo等,在資料寫入欄位,使用$objWriter->save($filename);要儲存時,就會發生錯誤訊息。
上網找尋答案,最佳的解法如下 :
原來這是PHPExcel "\PHPExcel\Writer\Excel2007.php"中的一個bug。
只要註釋掉或刪除第235-237行這三行程式碼(如下),問題就解決了
if (file_exists($pFilename)) {
unlink($pFilename);
}
2020年4月15日
CodeIgniter架站如何與Windows AD Server認證帳號密碼?
企業內用CodeIgniter架站,通常需要整合公司內部的帳號系統,特別是很多企業常用的Windows AD Server。如何做到呢?
說明如下 :
上面的程式也可以自己修改,客製符合您的需求。
2020年4月10日
[繁簡中文並存問題]PHP Web應用系統繁簡中文並存問題研究
,則無法處理。
提到"某些應用程式 (特別是 Web 應用程式) 必須處理以 UTF-8 編碼方法所編碼的 Unicode 資料會有
問題,因為SQL Server使用Unicode 編碼方式 (UCS-2),無法將 UTF-8 識別為有效的字元資料。
上。
全繁簡並存,是做不到的。
