最近回去看了Jace Ju​ 大大 於2015年在PHP也有Day 的返樸歸真系列之從實例學設計模式。Jace Ju 從物件導向開發原則一路講到設計模式,而且列舉各個原則及模式清楚易懂的範例,因此下面整理了一些重點分享給大家。

這篇文章會分享設計模式,不過如果搞懂SOLID的話,是否採用設計模式不是那麼的重要,設計模式主要的目的其實是提供解決的方式及方便工程師之間的溝通。

在PHP中常見的設計模式:

  1. Strategy Pattern 策略模式
  2. Simple Factory Pattern 簡單工廠模式
  3. Adapter Pattern 轉接器模式
  4. Decorator Pattern 裝飾者模式
  5. Chain of Responsibility Pattern 責任鏈模式
  1. Strategy Pattern 策略模式

情境: 同一個行為有數種方案可以選擇,使用者可以在執行期間再決定要用哪一個。

秘訣:

  • 出現用switch case來切換行為的場合
  • 將行為定義成介面,實做出同一體系的類別
  • 在方法參數中注入

範例: 訂單希望提供數種物流選項以計算運費,但每家一種都要修改訂單類別的程式碼。

class Order
{
public function calculateFee($shipmentName)
{
switch ($shipmentName) {
case 'Hsinchu': // 新竹貨運
$fee = .... ;
break;
case 'BlackCat': // 黑貓貨運
$fee = .... ;
break;
case 'PostOffice': // 郵局
$fee = .... ;
break;
default:
break;
}
}
}

增加物流就要修改上述程式碼,有修改錯誤的風險。

class Order
{
public function calculateFee(IShipment $shipment)
{
$fee = $shipment->getFee();
}…

  1. Basics
  • A class may contain:

▹ 1. 常量(constants)

▹ 2. 變量(Variables) — 屬性

▹ 3. 函式(functions) — 方法

  • new: 以new ClassName() 建立一個物件實例,除非有自行定義 constructor
  • Object Assignment : ​Store in different data slot but same object handle,Variable Assignment :​ 右邊表達式的值Copy一份傳給左邊(call by value)
$assign = $instance; // Object assign! 
$instance -> var; // $assign will have this value var_dump($instance);
var_dump($assign);

2. Properties

  • Properties declaration: public,protected or private + $variable
  • :: 用於呼叫 static property(屬性), static method(方法)及constant(常量)
  • -> 用於呼叫 non-static property, non-static method

3. Visibility

  • Public 任何地方都可以被使用,Protected 僅能於自身之Class或者繼承之Class內使用, Private 僅能在自身的Class當中使用
  • 使用原則是當有需要給外界使用的時候設定為public,否則權限應該以最小scope為原則。當有需要時才要考慮加大權限。private → protect → public

4. ​Class Constant

  • 可以將Class中始終保持不變的值定義為常量。在定義和使用常量的時候不需要使用$符號
  • 訪問constant方法是 ::

5. ​Constructors and Destructors

  • Constructor …

  1. if / elseif /else
  • Syntax: (can be nested)
if (expr) { 
statement
} elseif (expr) {
statement
} else {
statement
}

2. while

  • Syntax:
while (expr) { 
statement
}

3. do-while

  • 第一次迭代一定會執行!
  • 表達式的值在每次循環結束後檢查 → do-while
  • 表達是的值在每次循環開始時檢查 → while
  • Syntax:
$x = 0; 
do{
echo $x;
} while ($x > 0) ; //return 0

4. for

  • Syntax:
for ( expr1; expr2; expr3) { 
statement
}
// expr1:在循環開始前無條件求值一次
// expr2:在循環開始前求值,若為True則繼續循環,反之
// expr3:在循環後被求值且開始下一循環

5. foreach

  • 提供遍歷Array的簡單方式
  • Syntax:
// 每次循環中,值會賦予給$value,並且依照順序前進
foreach(array_expression as $value)
// 每次循環中,鍵會賦予給$key,值會賦予給$value
foreach(array_expression as $key => $value)
  • list(): 將Array中的值賦予一組變量,通常會用在function的return value,比如說當你的 function要一次return多個值,可以這樣用。
function getManyValues(){ 
return array(‘coffee’, ‘brown’,’caffeine’);
}
list($a,$b,$c) = getManyValues();
// $a = ‘coffee’
// $b = ‘brown’
// $c = ‘caffeine’…


  1. User-defined functions
  • 後面定義的 functions可以在前面呼叫它,但要注意下面兩種情形:

▹ Conditional function. (有條件函式)

實際上的應用如下,如果不存在,再放上function。
if (! function_exists(‘cdnify’)) {
function cdnify($path, $withMixed = true) { ……. }
}

▹ Functions within function. (函式中的函式)

2. Function arguments

  • PHP supports passing arguments in four methods:

▹ 1. Passing arguments by value.(預設都是傳值)

▹ 2. Passing by reference(參考記憶體)

▹ 3. Passing default argument values(預設參數值必須放在非預設參數後)

▹ 4. Passing non-scalar types(array, object, null) as default values

  • 參數型態宣告(Arguments Type declarations): 可以讓函式在被呼叫時要求丟入特定之參 數型態。

3. Returning values

  • return會立即中斷此函式的運行,並將程式碼帶到呼叫此function的地方
  • 若省略return,則返回值為NULL
  • return可以返回的對象包括:Value, Array, Object
  • Return Type Declarations:
function sum1(int $a, int $b): float { 
return $a + $b;
}
var_dump(sum1(1,2)); //float(3)
var_dump(sum1(1.8,2.5)); //float(3)

4. Variable functions

  • 簡單來說就是可以將function name用string來表達,代表你可以透過 string…

  1. Assignment Operators
  • 基本的賦值運算符是“=”,會將​右邊表達式的值Copy一份傳給左邊(call by value) ,但要注意Object Assignment是個特例
  • 組合運算符(Combined operators):
Addition:       $a += $b       $a = $a + $b 
Subtraction: $a -= $b $a = $a — $b
Multiplication: $a *= $b $a = $a * $b
Division: $a /= $b $a = $a / $b
Modulus: $a %= $b $a = $a % $b
Concatenate: $a .= $b $a = $a . $b

2. Comparison Operators

var_dump(“1” == “01”) //true
  • Equal (==) & Identical (===) & Spaceship (<=>)
  • Ternary operator 常用的技巧,如果只有一層,可讀性還可以
$title = isset($photo- > title) ? …

  1. Basic
  • PHP 中的變數用一個$符號後面跟變數名來表示。
ex: $var = ‘Bob’
  • Call by value && Call by reference:

▹ Call by reference: 加上 & 代表reference,就是去參考該變數的記憶體,二個變數會指向同一塊記憶體,所以不 管你改那一個,就都會去改同一塊記憶體

▹ Call by value: 沒有加 & 時,就是不參考,代表的是copy 一份出來,讓二個操作的是不同區塊的資料

  • 常使用isset()來檢測一個變數是否已被初始化。ex:
$title = isset($photo → title) ? $photo → title : ‘ ‘ ; 

2. Variable variables

  • 可變變量(Variable variables): 拿普通變量的值作為此可變變量的變量名稱。 ex:
$b = ‘hello’; 
$$b = ‘world’;
echo “$b”; //echo ‘hello’
echo “${$b}”; //echo $hello → world

3. Static Variable

  • 在使用laravel framework的情況下,static variable 會被使用到的機會十分的低。
  • static variable 會用在第一次被init 後,就能一直被reuse or access的東西,而且會記住上一次 的結果。 以下面的例子來說,如果你想從你的code 開始跑,就有一塊memory 被init ,之後只要在 function 內對static variable 操作,他都是會操作同一個memory。
function add_static(){ 

static $a = 0; //將此變數記錄在一塊memory當中

$a++;

return $a;

}

echo add_static(); //echo 1

echo add_static(); //echo 2

  1. Introduction

PHP 支援十種原始型別(primitive types):

Scalar types:

  • boolean
  • integer
  • float
  • point numbers
  • string

Compound types:

  • array
  • object
  • callable
  • iterable

Special types:

  • resource
  • NULL

2. Booleans

  • 將值轉換為boolean的方式 → (bool) or (boolean) cast
  • 下面這些當轉換為 boolean 時都會被視為False

▹boolean false itself.

▹integer 0

▹float 0

▹empty string and string “0”

▹array with zero element === null ⇐ return false

▹null NULL

3. Integers

  • 將值轉換為Integer的方式 → (int) or (integer) cast or intval() function
  • 若欲取整數 → round($var, $precision=0) or floor()

4. floating point numbers

5. String

  • 將值轉換為String的方式 → (string) cast or strval() function
  • 一個字串可以用下列4 種方式表示:

▹ 單引號(Single quote)

▹ 雙引號(Double…


前言

前陣子將php官方的document看完,紀錄下一些基本觀念及常踩到的雷。下列為依照文件進行分類,大家可以挑選有興趣的部分去了解。

Types

  1. Introduction
  2. Booleans
  3. Integers
  4. Floating point numbers
  5. Strings
  6. Arrays
  7. Objects
  8. NULL
  9. Type Juggling

Variables

  1. Basics
  2. Variable variables
  3. Static Variables

Operaters

  1. Assignment Operators
  2. Comparison Operators
  3. Incrementing/Decrementing Operators
  4. Logical Operators
  5. String Operators
  6. Type Operator

Function

  1. User-defined functions
  2. Function arguments
  3. Returning values
  4. Variable functions
  5. Internal (built-in) functions
  6. Anonymous functions(Closures)

Control Statement

  1. if / elseif /else
  2. while
  3. do-while
  4. for
  5. foreach
  6. break
  7. continue
  8. switch
  9. return

Class

  1. Basics
  2. Properties
  3. Visibility
  4. Class Constant
  5. ​Constructors and Destructors
  6. Object inheritance
  7. Scope Resolution Operator (::)
  8. Static
  9. ​Object interface
  10. Traits
  11. Type Hinting( = Type declaration)

前言

筆者最近常聽到MD5, SHA256,Base64, AES, RSA, 不知道大家對於這些名詞的了解程度到哪邊。 筆者一開始並不是很清楚他們之間的差異和應用的場景,因此這幾天看了一些文章,底下會將筆者所學習到的概念簡單的和大家介紹, 也當成是筆者學習的一個紀錄。

密碼學分類

密碼學主要有以下四種分類:

  1. 編碼&解碼(Encode&Decode)
  2. 單向雜湊(One Way Hash)
  3. 對稱性加密&解密
  4. 非對稱性加密&解密

接下來會來針對上述四種分類進行簡單的解釋。

編碼&解碼

編碼主要目的是為了要統一出一種方式可以讓資料在網路間傳送。像是我們可能在計算機概論當中常聽到的 ASCII, Unicode, UTF-8, base64 等等。編碼不會修改資料也不具備有加密的效果,單純就是換個大家都知道的方式來表達資料而已。下面讓筆者來介紹一下常見的編碼吧。

ASCII

電腦開始發展的時候,不同系統可能使用不同的編碼,導致在我的電腦可以看的東西傳到你的電腦之後卻變成一堆亂碼,ASCII就是為了解決這個問題而出現的編碼方式。

ASCII 編碼用了 7 bits,也就是最多能表示 2 的 7 次方共 128 種文字,包含26 個大小寫英文外、數字(0–9),還包含常見的控制字元與標點符號,也就是常常在計概課出現的考題,像是 32 = 空白,65 = A 等等,總共定義了 128 個符號。

不過缺點顯而易見,他只包含了英語系國家會用到的英文字母,像是其它國家的語言,例如繁體字這種需要 2~4byte 表示的字元就沒辦法處理。所以接下來才會發展出 Unicode 用來表示更多的字元。

Unicode Transformation Format (UTF)

由於上述提到ASCII編碼的問題,因此後來有科學家將全世界所有的文字與符號都收錄進一個巨大的表格內,並給予每一個字元一個獨一無二的代號(Code point)。這個概念就是我們今天所說的萬國碼(Unicode)。

UTF 編碼方式中又以 UTF-8 最為著名。UTF-8 用了 1~4 bytes 去表達一個字,向下相容 ASCII,也就是說UTF-8 的前 128 個字的編碼與 ASCII 完全相同,因此在處理英文字上不會有問題,而且當處裡到ASCII 無法正確表示的字元(如繁體字、日文)時,UTF-8 則使用多個 bytes 來表達該字元。

Base64

採用6個bits也就是 2 的 6次方共64個字元(大小寫A-Z+數字0–9+兩個符號)來表示二進位資料的編碼方式,例如下圖當中的這3個bytes(3 x 8 bits),在Base64編碼下,會用6個bits來表示二進位,因此會將這3個bytes編碼為4個字(TWFu),但若在擴展ASCII編碼下的話,則是會用8個bits來表示二進位,因此會將這三個bytes編碼為3個字(Man)…


前言:

之前在寫 Laravel的時後,如果遇到要debug的話,最常用的方式就是去下中止點,例如: dd() or var_dump()去印出目前的變數是不是如你所預期的。

最近知道 XDebug可以在Vscode中直接將變數都印出來,讓Debug起來更有效率。因此下面介紹一下該如何在laradock環境中安裝XDebug並且於Vscode中可以正確的Debug。

安裝步驟:

Step1. Laradock 中安裝 XDebug

修改 Laradock .env:

  • WORKSPACE_INSTALL_XDEBUG=true
  • PHP_FPM_INSTALL_XDEBUG=true

修改 Laradock/PHP-FPM & Laradock/workspace 的 xdebug.ini:

  • xdebug.remote_enable=1
  • xdebug.remote_host=”host.docker.internal”
  • xdebug.remote_connect_back=0
  • xdebug.idekey=VSCODE
  • xdebug.remote_autostart=1

註解:Remote host to be your localhost’s IP address → host.docker.internal:

Image for post
Image for post

Step2. Build Laradock

現在你已經完成所有laradock的設定了,接下來必須去重build並啟用你的workspace及php-fpm container。

  • laradock $ docker-compose down
  • laradock $ docker-compose build php-fpm workspace
  • laradock $ docker-compose up -d nginx mariadb

Step3. 安裝 VScode XDebug 套件

安裝Felix Becker 提供的 PHP Debug 套件

Image for post
Image for post

Step4. 連接 VScode 和 Laradock

  • 點擊PHP Debug Plugin的圖示
  • 點擊齒輪修改設定檔(launch.json)
  • 修改完設定檔後即可開啟XDebug功能
Image for post
Image for post

launch.json 修改如下:

{    "version": "0.2.0",    "configurations": [      {          "log": true,          "name": "XDebug listening to Laradock",          "type": "php",          "request": "launch",          "port": 9000,          "pathMappings": {             "/var/www/project": "/Users/andy/Desktop/project",          }       }   ]}

這邊要特別注意的是 pathMappings/var/www/project 是 docker 中的專案路徑,要映射到你本地端的專案路徑 。

參考資料:

https://medium.com/full-stack-development/laradock-xdebug-ms-code-no-problem-35a4338deb3f

Andy Chou

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store