Tag: php
-
CentOS 7 安裝、升級 PHP 5.6
轉眼間當年幫客戶架設的 server 也好幾年了。隨著程式碼的迭代,server 也到了不得不更新的時候了。不過目標沒有很遠,只要把 PHP 5.4 升到 5.6 就可以了。 把升級的過程筆記一下 首先是更新 EPEL 庫 yum install epel-release 或 rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm 接著更新 Remi 庫 rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm 檢查系統安裝了哪些和 PHP 相關的套件 rpm -qa | grep php 要升級的話要先移除舊套件。因為 PHP 版更,相關的 extension 都要換成相對應的版本才行。注意以下指令可能也會把 phpmyadmin 一起移除 yum remove php-* 啟用 Remi 庫,用編輯器打開以下檔案 /etc/yum.repos.d/remi.repo 找到這一段… 把 enabled 設為 1 [remi-php56] name=Les…
-
Best practice to generate random token in PHP
在 Stackoverflow 看到一篇超級實用的文:在 PHP 中產生隨機字串的最佳實踐。 產生隨機字串這個看似不起眼的議題實作起來還挺麻煩的,曾經為了如何產生字串跟同事討論了許久。 $length = 16; $token = bin2hex(openssl_random_pseudo_bytes($length)); # => e9bf18672b051619a3479ecbe1cb7d08 唯一的參數 $length 可以替換成任意整數,產生的字串長度就是 $length *2。 同場加映,Google Chrome 的亂數演算法也有改過。
-
How to Flatten a Multidimensional Array in PHP?
最近碰到的小需求:如何將多維陣列攤平成一維陣列?…. 本來以為 PHP 那巨大的 Lib 會有一個神奇的 function 完成這任務,結果翻了一遍 php.net 的文件,沒有找到這神奇的功能。不過還是有另一個神妙的 function 可以拿來用,那就是 array_walk_recursive,這個 function 會有遞迴的方式走完整個 array,然後看使用者後續想幹嘛… 以攤平一維陣列為例,以下是只保留 value 的作法… function flatten(array $array) { $return = array(); array_walk_recursive($array, function($a) use (&$return) { $return[] = $a; }); return $return; } 如此一來就可以將多維陣列轉為一維。若是要保留 key 與 value,要注意 key 名稱是否有重複 (isset)。
-
強制 fputcsv 所有欄位都加上雙引號
公司跟一家新廠商展開合作,其中交換電文是用 CSV 格式。但對方要求所有的欄位都要用 ” 雙引號包起來。看起來就像下圖這樣。 但是很不巧的,PHP 內建產生 CSV 的指令 fputcsv 沒有提供強制的選項。做出來的檔案如下圖。 山不轉只好路轉… 在丟進 fputcsv 前就先用雙引號包一包。 比較特別是 fputcsv 原本的 enclosure 字元預設就是雙引號,無法替換成空白,只好用 chr(0) 來跳脫,不然每一筆資料會變成 “””aaa”””,三個引號… 這樣就可以交差了。
-
Connection could not be established with host
最近重灌了工作用的筆電,把開發環境的 PHP 升級到 5.6.10,然後就各種狀況….. 其中一個問題是從本機連不上公司 mail server,所以寄信功能就掛掉了。Laravel log 的訊息如下 local.ERROR: 500 – Connection could not be established with host xxx.com.tw [ #0] @ / exception ‘Swift_TransportException’ with message ‘Connection could not be established with host xxx.com.tw [ #0]’ in laravel/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php:270 原來是因為從 PHP 5.6 開始,變更了 SSL 認證的預設值,verify_peer 與 verify_peer_name 這兩項安全檢查都被改為預設,然後很多 SSL verification 就過不了。雖然提高安全性是好事,但開發環境卻造成一些困擾。 以上述的 swiftmailer 套件為例,它的…
-
Laravel: failed to open stream: Too many open files
公司的 Team 開發的產品也越來越龐大了,API 的部份依賴 Laravel 內建整合的 PHPUnit 來進行自動化測試。 這回從 git repo 上拉了新的 code 後,照慣例跑一下 phpunit,然後就掛了… PHP Warning: failed to open stream: Too many open files 好像沒見過這樣的訊息。Google 一下才知道是踩到了 Mac OS 檔案開啟上限的地雷。 $ ulimit -a # 這個指令可以看系統限制 core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes,…
-
How to override the path of PHP to use the MAMP path?
最近在學習 Laravel Framework 的使用,現在 PHP 許多 Library、Framework 都改用了 composer.phar 這個套件管理功能。 其中許多管理功能需要在 command line 輸入指令,但是 Mac 其實也有內建 PHP,卻缺了許多常用的套件。 與其去補安裝套件,不如改用 MAMP 的 PHP 還比較省事。 在 ~/.bash_profile 加入以下指令: export PATH=”/Applications/MAMP/bin/php/php5.5.3/bin:$PATH” 這樣使用 PHP 指令就會自動選用 MAMP 下的版本和套件,其中紅字請改為您使用的版號。
-
PHPExcel: Delete sheets
PHPExcel 是 PHP 所有第三方套件裡,功能相當強大的一款,主要用途是用來讀寫 Excel (.xls)、Excel 2007 (.xlsx)、Libre/OpenOffice Calc (.ods)、CSV 等等各種試算表文件。 儘管是個強大的套件,個人倒是覺得這套件的語法相當複雜、不夠直覺,文件也不是非常容易閱讀,往往還是去找 stack overflow 的範例更快。 最近在幫客戶開發報表的功能,匯出 Excel 試算表是常見的作法。寫著寫著,突然想到每次產生只有一個 sheet 的試算表,都會被自動再加一張空白的 sheet … 就像下圖這般。 然後就…. 很想刪掉它 XD 在 stackoverflow 沒看到討論,倒是官方論壇有討論到,用法難得的直覺 (?)。 $objPHPExcel->removeSheetByIndex(1); 參數是第幾個 sheet,從 0 開始,所以要刪除 [Worksheet 1],就代入參數 1 醬。
-
Detect Browser Language in PHP
最近某個已經上線的專案新增了製作多國語系介面的需求,流程上打算用 PHP 來偵測使用者瀏覽器的語言設定。
-
Force SSL/https using mod_rewrite or PHP
工作需求,要幫某網站全部轉為 HTTPS 加密傳輸。 有兩種方法,一是透過 .htaccess,二是用 PHP 來處理。 用 .htaccess 處理的方式如下 RewriteEngine On RewriteCond %{HTTPS} !=on RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] 用 PHP 來處理: if (!isset($_SERVER[‘HTTPS’]) || $_SERVER[‘HTTPS’] !== ‘on’) { if(!headers_sent()) { header(“Status: 301 Moved Permanently”); header(sprintf( ‘Location: https://%s%s’, $_SERVER[‘HTTP_HOST’], $_SERVER[‘REQUEST_URI’] )); exit(); } } 個人比較偏好用 .htaccess 來處理。不過若是沒有全部頁面都需要的話,PHP 比較方便。
-
Check if PHP session has already started
用 PHP 寫系統基本上躲不掉 session 相關的一系列問題的。因為個人偏好 CodeIgniter,所以很多時候用 Session Library 或是開源的 Native Session Library 就可以避開一些煩瑣的麻煩。 不過很多時候碰到沒有使用 framework 當基礎,直接用 PHP 開發的專案時,程式碼裡 “充斥” 著 session_start() 也是非常普遍的事情,接著就會一直在 error_log 裡看到這樣的訊息: PHP Notice: A session had already been started 看了有夠礙眼,也讓人覺得很不專業。 其實這問題是可以避免的。只要在宣告前檢查是否啟動就好。 isset($_SESSION) or session_start(); 如果使用的是 PHP 5.4 以上的版面,還有更可靠的寫法。 (session_status() !== PHP_SESSION_ACTIVE) or session_start(); 乾乾淨淨的是 error_log 才是開發者的王道。
-
Disable Cache for PHP 5.5.3 in MAMP
前些時間接手一個已經上線的案子,進行改版作業。從 Git 上把 code 拉下來,執行一下就… 爆了。發現同事用了相當新的 PHP 語法。我本機的開發環境是 PHP 5.2.x,無法執行。 馬上想到 MAMP 可以切換成新的版本,切換成 5.5.3 問題就解決了。
-
Bookmark: Hashids, Generate short hashes from numbers
以前寫過自己的短網址服務,不過那時候很多計算,尤其是網址的編碼都是亂寫一通。跟朋友討論的時候才曉得用 base36 之類的方法編碼。 最近又碰到一個需求,需要將幾組參數編成較短的字串,在 StackOverflow 上亂逛找到了 Hashids 這個好東西。支援多種語言、可自訂 salt,可編多組參數,最重要是這是雙向的,可以解回來。完全符合需求。 ps. 其中 PHP 版的範例有用到 namespace,把源碼的 namespace 註解掉就可以在 PHP 5.3 以下使用。
-
Codeigniter: Check if libraries/helper/core files is loaded
使用 CodeIgniter 框架開發時,會透過 $this->load->library() 之類的方法來載入特定的檔案。在 CI 的 routing 規則中,同一個檔案只會被載入一次,因此多寫幾次 $this->load->library() 是不會發生什麼慘劇的。 不過有時候還是想確認到底某 class 有沒有載入過,而不想到處丟 $this->load->xxx() 的話,可以用以下方法來確認。 if (class_exists(‘Library’)) { $this->library->myMethod(); } 要注意的是 CI 有別名的規則,比如說有個 model 叫 ‘file_model’。使用別名載入時,會寫成以下 $this->load->model(‘file_model’, ‘file’); $this->file->do_something(); 這種情況下,若要檢查是否已載入,要用原名。如下: if (class_exists(‘File_model’)) { // do something }
-
Fix Sublime Text’s quirky PHP variable selection
Sublime Text 是近來相當受歡迎的文字編輯器,快速、方便的操作介面對程式開發有很大的助益。這也是我目前在 Mac 上主要的文字編輯器。 不過在開發 PHP 的時候,Sublime Text double click 選字卻不會選到 PHP 變數前的那個 $ 錢字號。一開始還蠻困擾的,但實際用起來好像不太影響我寫程式的流程,所以就放著不管了。 But! 我同事問了… 他說這個讓他很困擾,有沒有辦法在 double click 的時候連 $ 一起選起來。 Sublime Text 幾乎所有的參數都能改,這也是這個編輯器很妙的地方,可以高制客製化。 先開啟 Packages 路徑… Sublime Text > Preferences > Browse Packages… 打開後進入名為 User 的資料夾,新增一個純文字檔,命名 PHP.sublime-settings。 裡面貼上這段文字後存檔離開,Sublime Text 會馬上生效。 { “word_separators”: “./\\()\”‘-:,.;<>~!@#%^&*|+=[]{}`~?” } 這樣點兩下選取變數就會連 $ 一起選起來了。
-
Run a PHP script from the command line with MAMP
我在 Mac 上開發 PHP 一直是用 MAMP 這個好用的 App。不過如果碰到需要在 Terminal 下以指令方式執行 PHP 程式就有點麻煩。 MAMP 裡的 php 路徑頗長…. 像這樣… /Applications/MAMP/bin/php/php5.3.6/bin/php -v # 查詢 PHP 版本 所以還是來修改一下 ~/.bash_profile 吧。如果沒有這個檔案,自己建一個。 在裡面加入這一行… export PATH=/Applications/MAMP/bin/php/php5.3.6/bin/:$PATH 存檔後離開。 在 Terminal 下輸入 source ~/.bash_profile 會重讀設定檔,然後剛才的修改就生效了。這樣以後要執行 PHP script 直接輸入 php 就可以了,方便許多。
-
PHP FIG Group PSR standard 程式風格
這兩天在查資料的時候才知道有 PSR 風格。這是由 PHP FIG Group 所訂的規範。FIG 這個組織是由一群開發 Open Source PHP 專案的開發者所組成,目的在於以最低程度的限制來統一各個專案的 coding style,避免各家自行發展的風格阻礙了程式設計師撰寫的困擾。 PSR 規範有四套,分別為 PSR-0 (Autoloading standard) PSR-1 (Basic Coding Standard) PSR-2 (Coding Style Guide) PSR-3 (Logger Interface) 依順序有繼承性,每一篇都很簡短,蠻建議看看。
-
PHP: Finding the year quarter for a date
在工商業應用中,時間紀錄是系統中非常基本的東西,不過時間的表示方法就五花八門了。最近碰到一個需求是同一個時間欄位可能是 Y-m-d (ex. 2012-11-29)、quarter (Q4 2012)、month (Nov 2012),或是 year (2012),甚至是 TBA (to be announced)。 其中轉換成季 (quarter) 會用到一點點技巧,在此筆記如下: <? $timestamp = mktime(0, 0, 0, 11, 29, 2012); echo ceil(date(“m”, $timestamp)/3); ?> 只要前面再加個 ‘Q’ 就是第幾季了。 在資料庫部份如何分辨客戶是儲存哪種型態,我的做法是多開一個 date_type 的欄位。 CREATE TABLE `calendar` ( `c_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `c_date` date NOT NULL, `c_date_type` char(1) NOT NULL DEFAULT…
-
Sharpen an image using PHP and GD
同事正在開發一個購物平台,店家可以上傳商品照片,由系統自動縮圖到適合版面的大小,不過 resize 後圖片品質明顯下降,於是同事問我有沒有解法。同事問我並不是因為我比較強,只是因為我的位子在他旁邊。 跟同事討論了一下,試用了 imagecopyresized 和 imagecopyresampled 兩個函式來縮圖,前者的細節比較好,但部份線條出現明顯的變形,後者圖形正確,但看起來比較模糊。所以先用後者縮圖,再想辦法銳化圖片。 印象中 PHP GD Library 並沒有直接提供 sharpen (銳化) 相關的函式,但是 Google 一下,發現有 imageconvolution 濾鏡可以用,真是有趣,沒想到可以自訂濾鏡,以前在學校修過影像處理課程的回憶…. 都忘光光了。還好不難找到幾組範例。 <?php // create the image resource from a file $i = imagecreatefromjpeg(‘otter.jpg’); // define the sharpen matrix $sharpen = array( array(0.0, -1.0, 0.0), array(-1.0, 5.0, -1.0), array(0.0, -1.0, 0.0) ); // calculate the sharpen…
-
PHP: Constrains a value to not exceed a maximum and minimum value
幾年前在寫 Processing (P55) 的時候,有個方便的 function 叫 constrain。用法是 constrain(value, min, max) 例如 float mx = constrain(mouseX, 30, 70); 當 mouseX 大於 70 時就回傳 70,小於 30 時就回傳 30,將值限制在 30 ~ 70 這個區間。因為 Processing 大都是拿來寫互動、視覺方面的程式,所以用到此功能的頻率頗高。後來轉換跑道寫其他語言時,發現好像都沒有這個方便的函式。 最近又有 constrain 的需求,想起幾年前見過有人用 min, max 來代替,寫法如下。 <?php function constrain($value, $min, $max){ return max( min( $value, $max), $min); } echo constrain(29.3, 30, 60); ?>