[教學] CodeIgniter 4 快速上手 (ㄧ) 下載與安裝

CodeIgniter 是一個PHP 基底的框架,由於PHP7的執行效率比PHP5好,所以CodeIgniter 4 幾乎重寫了整個架構,採用PHP7作為基底,並於2020年5月1號正式發布,沒錯!就是今年的勞動節,趁著它發表還沒多久,我們就來試試看看有哪些坑要採吧!

開始開發前請確定你的電腦裡有足夠可以運行PHP7.2以上的環境,並且搭配Mysql或MariaDB資料庫,如果這個部分不會的朋友,建議google一下xamppmampampps等等的其中一套LAMP套裝軟體,以快速建置你的本機PHP執行環境。
無廢話開始教學!第一步就是安裝CodeIgniter 4,你可以透過 Composer下載,也可以用 git 從 github上clone下來,本篇要教的是連程式小白都會的從官網直接下載法!跟著以下步驟保證你零基礎也沒問題啊!
  1. 前往CodeIgniter 官網下載 CodeIgniter 4 
    前往CodeIgniter 官網下載 CodeIgniter 4

  2. 下載回來直接直接解壓縮,會出現一個framework-4.X.X,把該資料內的檔案全數複製貼到你的開發環境中。
  3. 接著因為這個東西是外國人發明的,所以我們要添加語系包,讓錯誤訊息可以中文化,因此我們一定要到官方的github下載多國語言語系包,下載回來之後將「/Language」內的zh-tw資料夾,貼到我們開發環境中的「app/Language」內即可。
    到github下載多國語言語系包

  4. 確定你的的開發環境是有正常啟動的,然後開啟你開發環境中的“/app/Config/App.php” ,確定第24行的public $baseURL 的設定符合你的本機環境。有些人要改成http://localhost 或是 http://localhost:8080,有些人可能是自訂名稱,像我用mamp我就是用內網ip的模式,所以這裡每個人都可都有點差異。
    開啟你開發環境中的“/app/Config/App.php” ,確定第24行的public $baseURL 的設定符合你的本機環境

  5. 設定完baseurl 變數之後,我們要往下設定第66行的「$defaultLocale」,將其從en設定成「zh-tw」,也就是我們步驟3所複製的那個Language資料夾,如此一來我們就把錯誤訊息都設定成繁體中文了!
  6. 時區的部分也不要忘記了,讓我們繼續往下看到第102行的「$appTimezone」,把America/Chicago改成「Asia/Taipei」,到這邊這個App.php設定檔就差不多完成了。
  7. 我們回到開發環境的根目錄,將public資料集裡面的「.htaccess」跟 index.php 複製一份到根目錄,接著打開你剛剛建立在根目錄的index.php,將16行的「../」移除,如下圖:
  8. �在瀏覽器中開啟你的本機測試環境,你就可以看到歡迎頁了!

    CodeIgniter 4 welcome歡迎頁

  9. 如果你想要開啟除錯模式,在CodeIgniter 4 你可以快速切換成開發模式來開啟除錯模式,只要在根目錄找到檔名env的檔案,將其複製一份,並重新命成成「.env」,然後將裡面的第17行設定成「CI_ENVIRONMENT = development」 即可快速切換成開發模式,當然你也可以改回「CI_ENVIRONMENT = production」即可關閉。
以上就是本次的CodeIgniter 4 下載與安裝的教學,如果有哪邊寫錯或不清楚的地方麻煩留言告訴我,我會盡快修正的。

[教學] 我們來用CRM吧!EspoCRM、vtigerCRM 與SuiteCRM

公司營運至今也有三、四年,一直以來都用很傳統的方式在整理檔案,並沒有採用任何CRM系統,常用客戶才會有登記在客戶的excel表裡,是的,我們用excel當作我們的CRM,就這樣用了兩年,雖然說沒有遇到執行上的問題,但是我總覺得我們一直在浪費這項資源,畢竟開發每一個客戶都要花很多時間,但是這些客戶開發後沒有再繼續維持的真的比想像中多很多,尤其是早期我們建置的網站,大部分客戶都還用到現在遲遲不肯更新,以至於我們跟客戶的緣分就僅止於一個網站開發的時間,緣分慎短,說來可惜。我們可以幫客戶的部分不光只是建立網站,還可以協助客戶拓展網路事業,透過網路我們可以幫你創造更多的價值,這才是我們團隊真正專業的地方。

如此這般的,我們來用CRM吧!

雖然我們擁有開發能力,但是一套專業的CRM勢必是要花許多時間才可以建立,雖然說近期公司專案上是有空檔,但是這空檔也不夠開發一整套完整的CRM,畢竟一套完整的CRM除了要可以掌握客戶名單以外,報價單、合約、發票等三大區塊也是基本必備的功能,另外還要可以發送email,如果報價單、合約可以透過系統產生並且自建流水編號,當然就會讓一切更有系統,搜尋也可以更加便利,其他功能像是服務或產品管理、日曆、會議或是銷售流程等等也是很重要的功能,這樣隨便列一列都可以開發出很多功能來,與其自己抽空開發,我想最快的方式還是尋找市面上的open source來解決問題,雖然不見得非常符合需求,但是至少是個不錯的開始!

透過Google,我找了好幾套open source的CRM來測試,像是SuiteCRM、VtigerCRM,還有一套叫EspoCRM,這些都是開源免費的CRM系統,我們就台一套一套好好介紹吧!

簡單易用的EspoCRM

EspoCRM內建多國語言,不需要另外安裝語系包,內建簡體中文可用,但是沒有繁體中文,介面操作上非常簡單易用,是採用左右兩欄設計,算是一套簡單小巧又容易上手的CRM系統,功能部分有客戶(公司)管理、聯絡人(窗口)管理、潛在顧客、商機、案例、電子郵件、日曆、會議、通話、任務、文件、行銷活動、知識庫、信息流、用戶管理,大部分命名都很淺顯易懂,操作上也不太需要特地學習,左手邊就是功能選單,新增一律在右上角,內容上方是搜尋,下方則是列表,是一套我覺得如果我們家也要開發CRM應該也會朝這個方向前進,畢竟這套CRM的介面操作邏輯與我們現在幫客戶客製化的後台管理系統操作邏輯是完全相同的,所以對我來說,一但架好我幾乎不用學習就可以立馬開始使用。

那既然EspoCRM這麼簡單易用,我為什麼沒有選擇它呢?原因是因為他少了數據分析、產品與服務、發票管理等部分。現今講求大數據的時代,凡事都必須要有有數據為依據,EspoCRM在這部分就顯得非常聰明,數據分析的功能你必須另外付費購買EspoCRM Advanced Pack,在這個Advanced Pack裡,你可以獲得報表、商業流程管理、工作流程、MailChimo串接、Google行事曆同步、Google聯絡人串接、產品管理、報價與發票管理。那這個Advanced Pack要多少錢呢?要美金495元,約台幣1萬5千元。雖然說EspoCRM非常簡單易用,但是在我還有其他選擇的情況下,這個1萬5千元要不要花就會變得很重要,再者我們只是一間小小工作室,還是要考慮成本問題,與其花1萬5買這個Pack,我可能寧願花在團隊的年度聚會上,因此這個EspoCRM到這裡就被我拋棄了。

你可以在這裡前往EspoCRM官方網站,也可以在這裡試用EspoCRM包含Advanced Pack的版本。

選單清晰有條理的vtigerCRM

vtigerCRM算是老牌open source CRM,是從更老牌的sugerCRM修改而成,而目前sugerCRM最新版本已經要付費購買,vtigerCRM最新版還是完全開源的。在選單的邏輯上顯得非常有調整,你很快就可以找到你所需要的項目,主要分成:行銷、銷售、庫存、支援、專案與工具等項目,對於產品的進銷存也是有不錯的管理,除了可以掌握客源也可以掌握供應商來源,如果不是銷售類也可以透過支援與專案進行服務類商業行為管理,算是不管各種商業模式支援度都是一等一的CRM軟體,也是我心中目前的第一優先選擇。

最後我沒有採用vtigerCRM的原因,在於目前vtigerCRM 7 並沒有繁體中文語系,語系安裝也需要通過擴展商店才能安裝,雖然有找到一些台灣的工程師自行開發的繁體中文資訊,但是礙於這些工程師不喜歡大家直接當伸手牌的緣故而沒有釋放出來,原本我想自個翻譯,但是進行了三天之後我就放棄了,原因是我的翻譯我自己覺得很怪,而且又沒有翻譯軟體的經驗,怕到時候翻譯出來變成四不像,導致好好一個CRM變的很難用,這也變成了我最後沒有選擇vtigerCRM的原因。另外對於vtigerCRM這樣包山包海的功能我其實也有點擔心,畢竟我想要的只是一個客戶管理系統,這樣包山包海真的好嗎?裝了一套超厲害的CRM但是我只會用到50%的功能這樣好嗎?反覆思考下我覺得似乎不太妥,所以即使是第一優先選擇,也漸漸的在我的清單中被劃掉了。

你可以在這裡下載最新版的vtigerCRM

怪複雜又難懂的suiteCRM

suiteCRM與vitgerCRM一樣是來自於老牌的sugerCRM修改而成,所以本質上與vitgerCRM應該是差不多的,但是suiteCRM的選單就不像vtigerCRM那樣的好理解,雖然大部分vtigerCRM有的,suiteCRM也有,不過仔細核對後就會發現,suiteCRM少了供應商與支援區塊,所以讓suiteCRM可使用的範疇變得沒有vtigerCRM這樣的寬廣,雖然說功能變少,但是卻讓suiteCRM可以更專注在客戶維護、專案流程上,對於我們這種小型工作室來說,已經算很夠用了。

最後讓我選擇suiteCRM的原因也很簡單,suiteCRM擁有繁體中文語系翻譯檔,也就是大部分的操作都可以在中文介面下進行,所以也會讓學習門檻稍微降低一些,對於英文不好的我或其他同事來說也會更簡單。另外在系統擴充與設定的部分suiteCRM比vtigerCRM好非常多,suiteCRM不需要經過擴充市集進行擴充安裝,這意味著大家可以隨時開發擴充,擴充的發展就會比vtigerCRM來得自由一些,但是太過自由最後當然管理不易,最後當然還是回歸到vtiger那樣有擴充市集管理會比較好一些,suiteCRM深知這個道理,所以目前suiteCRM已經擁有線上市集,你可以從裡面找到很多不錯的應用跟佈景,數量遠遠多過vtigerCRM,付費方式有一次付清也有月租、年租等付費方式。

而suiteCRM本身在系統設定的部分,自由度也跟擴充一樣超級高,而且內建系統修復功能,像這樣龐大的系統難免會有出相障礙的時候,有內建系統修復功能的情況下,對於不了解程式的使用者或是對這麼龐大的系統感奈無奈的工程師就顯得非常體貼。再來studio工作室功能,這個翻譯在一開始我根本看不懂,後來嘗試了一下才發現原來這是資料庫與介面修改器,當我發現目前的欄位不符合使用時,我可以透過studio工作室自行新增,並且調整介面,這個功能除了可以修改繁體中文語系檔翻譯不確實的問題,而可以讓CRM系統更符合整體公司的流程,有鑑於這個studio的功能還有繁體中文語系的情況下,讓suiteCRM即使不是我心中的第一名,也雀屏中選了!

你可以在這裡下載最新版本的suiteCRM,與繁體中文語系

在試用了suiteCRM一週之後,是發生了一些問題,但是就整體流程來說是非常符合我的需求,所以目前在快樂使用中,如果你也是一個小型的服務類型公司,我也會推薦你使用suiteCRM!

[php] 快速分割datetime資料

這其實沒什麼了不起,但是我五六年的菜菜鳥就是不常用,所以一天到晚都忘記,乾脆寫一篇放在部落格裡,這樣我就不會忘記了!

一般的datetime格式產出的資料會是像這樣“2015-09-08 02:28:07”,以前光是要把年月日時分秒拆開就要寫很多explode,就算要把日期跟時間差開也要寫一個explode,像這樣
$datetime = '2015-09-08 02:28:07';
$date_time = explode(' ', $datetime);
//$date_time[0]=2015-09-08
//$date_time[1]=02:28:07

如果我們要拆成年、月、日、時、分、秒就更麻煩了,就會變成這樣
$datetime = '2015-09-08 02:28:07';
$date_time = explode(' ', $datetime);
$date = explode('-', $date_time[0]);
$time = explode(':', $date_time[1]);
//$date[0]=2015
//$date[1]=09
//$date[2]=08
//time[0]=02
//time[1]=28
//time[2]=07

所以就會有一種怎麼越寫越複雜的感覺,事實上如果你會正規表達式,那就神奇了,因為只要一行就解決了 list($year, $month, $day, $hour, $minute, $second) = preg_split('/[-: ]/', $datetime);
//var_dump($year, $month, $day, $hour, $minute, $second);
所以新東西還是要加減學一下,這樣才可以提升自己的效率啊!

[筆記] opencart 1.5.6.1 後台 Sort Order 排序數字無法正常顯示

最近朋友開了一間店,因為預算有限又想用最快速度完成購物網站,所以就用Opencart來製作,本來打算裝2.0,但是朋友買版型只適用1.5.6,所以只好裝1.5.6版本,在上稿的過程中,編輯分類的時候發現在列表裡面的排序數字一直都不對,所以就回去查了一下程式,原來是原本的程式筆誤,導致 opencart 最終發佈的1.5.6.1版本裡面有bug,修改方式如下:

1. 找到admin/model/catalog/category.php,並用編輯器打開。
2. 尋找208行$sql = "SELECT cp.category_id AS category_id, GROUP_CONCAT(cd1.name ORDER BY cp.level SEPARATOR ' > ') AS name, c.parent_id, c.sort_order FROM " . DB_PREFIX . "category_path cp LEFT JOIN " . DB_PREFIX . "category c ON (cp.path_id = c.category_id) LEFT JOIN " . DB_PREFIX . "category_description cd1 ON (c.category_id = cd1.category_id) LEFT JOIN " . DB_PREFIX . "category_description cd2 ON (cp.category_id = cd2.category_id) WHERE cd1.language_id = '" . (int)$this->config->get('config_language_id') . "' AND cd2.language_id = '" . (int)$this->config->get('config_language_id') . "'";
3. 將上方紅色文字改成“cp.category_id” 變成+ $sql = "SELECT cp.category_id AS category_id, GROUP_CONCAT(cd1.name ORDER BY cp.level SEPARATOR ' > ') AS name, c.parent_id, c.sort_order FROM " . DB_PREFIX . "category_path cp LEFT JOIN " . DB_PREFIX . "category c ON (cp.category_id = c.category_id) LEFT JOIN " . DB_PREFIX . "category_description cd1 ON (cp.path_id = cd1.category_id) LEFT JOIN " . DB_PREFIX . "category_description cd2 ON (cp.category_id = cd2.category_id) WHERE cd1.language_id = '" . (int)$this->config->get('config_language_id') . "' AND cd2.language_id = '" . (int)$this->config->get('config_language_id') . "'";
4. 修改完成後上傳覆蓋admin/model/catalog/category.php,即可修復Sort Order 排序數字問題

[php]PHP in a Tweet 用140字寫完PHP功能

大家都知道Twitter一篇只能發表140字元的內容,所以只要在140個字以內的東西都可以發表出來,而PHP in a Tweet 是一個運用140發表出可用的PHP程式的活動,這種感覺其實非常的微妙,對PHP沒有說很熟悉的我來說,更是非常的有趣且特別,這個活動的規則也非常的簡單易懂:

1. 必須使用正規PHP撰寫
2. 最後的結果必須是echo "結果"或是return "結果"
3. 開始標籤(<?)與結束標籤(?>)可省略

由於規則非常簡單,所以參加的人也蠻多的,如果你有在玩Twitter,而且也會寫PHP,可以考慮參加一下這個140寫完PHP的活動噢!

詳細內容請見:PHP in a Tweet

[mysql]MD5加密 VS. sha1加密

一般建立會員資料的時候,密碼都會使用加密來隱藏密碼,這樣做可以避免哪天資料庫被駭客入侵,這樣大批會員權益會受損的危險,但是加密方式這麼多,到底哪一種加密方式比較好?就以往我的經驗來看,會員部分加密有使用MD5或Sha1加密,到底哪一種加密方式比較安全呢?

而到底什麼是MD5加密呢?

MD5的全名是Message-Digest Algorithm 5Message-Digest Algorithm 5(資訊-摘要演算法 5),是基於MD2、MD3和MD4,,在90年代初由MIT Laboratory for Computer Science和RSA Data Security Inc的Ronald L. Rivest開發出來的。是一種不可逆的加密算法,目前還沒有實際可以反逆推回的公式,但已有網站提供暴力破解MD5的資料查詢。

那什麼又是SHA1加密呢?

SHA1其實是SHA家族中的其中一員,SHA的全名是Secure Hash Algorithm(安全雜湊演算法) ,是由美國國家安全域(NSA)所設計,並由美國國家標準與技術研究院(NIST)發佈;是美國政府標準。而SHA1是基於MD5發展而來,SHA1比MD5多32位密文,所以更安全,但由於長度較長,所以使用SHA1的運算時間會比MD5還長一些。

最後簡單整理一下:

明碼 = 不加密,安全度為0
md5 = 比較安全,但是容易破解
sha1 = 比md5安全
sha256 = 比sha1安全
sha 512 = 比sha 256安全