C++ 設計模式 - 觀察者模式 Observer Pattern

今天你訂閱了一個喜歡的 YouTube 頻道,這個頻道一旦有新影片發布,你就會收到通知。不需要你反覆檢查頻道是否有新內容,所有更新自動發送到你手上。在軟體開發中,我們常常需要處理這樣的情境,當一個物件的狀態發生變化時,其他相關物件需要自動更新,並做出相應的回應。這種情境下我們就可以運用觀察者模式 Observer Pattern。

什麼是觀察者模式?

觀察者模式是一種行為設計模式,它定義了一種一對多的依賴關係,當一個物件(被觀察者)發生改變時,所有依賴它的物件(觀察者)都會自動收到通知並更新自己。這讓系統中的物件之間能夠鬆散耦合,保持靈活性和可維護性。

觀察者模式在 YouTube 訂閱的應用

在這個範例中,我們將 YouTube 頻道視為「被觀察者」,訂閱該頻道的使用者則是「觀察者」。當頻道有新影片上傳時,所有訂閱者都會自動收到通知。讓我們用 C++ 來實踐這個概念。

我們定義一個 Observer 介面,所有的觀察者(訂閱者)都要實作這個介面。

1
2
3
4
5
class Observer {
public:
virtual void update(const std::string& videoTitle) = 0;
virtual ~Observer() = default;
};

接著我們定義一個 Subject 介面,讓被觀察者(YouTube 頻道)管理觀察者的訂閱和通知。

1
2
3
4
5
6
7
class Subject {
public:
virtual void addObserver(std::shared_ptr<Observer> observer) = 0;
virtual void removeObserver(std::shared_ptr<Observer> observer) = 0;
virtual void notifyObservers() = 0;
virtual ~Subject() = default;
};

接下來我們實作一個具體的 YouTubeChannel 類別,這個類別代表 YouTube 頻道,當有新影片發布時,它會通知所有的訂閱者。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class YouTubeChannel : public Subject {
private:
std::list<std::shared_ptr<Observer>> subscribers;
std::string latestVideo;

public:
void addObserver(std::shared_ptr<Observer> observer) override {
subscribers.push_back(observer);
}

void removeObserver(std::shared_ptr<Observer> observer) override {
subscribers.remove(observer);
}

void notifyObservers() override {
for (const auto& observer : subscribers) {
observer->update(latestVideo);
}
}

void uploadNewVideo(const std::string& videoTitle) {
latestVideo = videoTitle;
notifyObservers();
}
};

最後我們可以定義多個觀察者來代表不同的訂閱者,他們會在接收到新影片通知時,顯示影片的標題。

1
2
3
4
5
6
7
8
9
10
11
12
class Subscriber : public Observer {
private:
std::string name;

public:
Subscriber(const std::string& name) : name(name) {}

void update(const std::string& videoTitle) override {
std::cout << name << " received notification: "
<< videoTitle << std::endl;
}
};

當我們將 Subscriber 加入 YouTubeChannel 的訂閱者清單時,頻道一旦上傳新影片,所有的訂閱者都會自動收到通知。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main() {
YouTubeChannel channel;

std::shared_ptr<Subscriber> alice = std::make_shared<Subscriber>("Alice");
std::shared_ptr<Subscriber> bob = std::make_shared<Subscriber>("Bob");

channel.addObserver(alice);
channel.addObserver(bob);
channel.uploadNewVideo("First Video");

channel.removeObserver(bob);
channel.uploadNewVideo("Second Video");

return 0;
}

執行上述程式碼,我們會得到以下輸出:

1
2
3
Alice received notification: First Video
Bob received notification: First Video
Alice received notification: Second Video

這個範例中使用了觀察者模式來模擬 YouTube 訂閱系統。當 YouTube 頻道上傳新影片時,所有的訂閱者都會自動收到通知。這讓我們的系統能夠更靈活地應對訂閱和通知的需求。

觀察者模式的優點

以這個例子來說,使用觀察者模式降低了耦合度,訂閱者和 YouTube 頻道之間的關係是鬆散的,YouTube 頻道不需要知道實際上是誰訂閱了它,它只需要通知所有訂閱者,這讓系統更容易擴展跟維護。

同時也具備擴展性,你可以輕鬆地新增或移除訂閱者,而不需要修改 YouTube 頻道的程式碼。

總結

觀察者模式是一種常見的設計模式,能有效處理多個物件之間的通知和更新需求。在我們生活中無所不在,例如:股票價格變化時,關注該股票的投資者都會收到通知,天氣變化時,訂閱天氣服務的使用者都會收到更新,電子報發布時,訂閱的讀者也會收到信件。下次你在設計系統時,如果遇到一對多的依賴關係,並且希望它們能夠自動更新的情況,不妨試試觀察者模式!

C++ 設計模式 - 策略模式 Strategy Pattern

在日常開發中,我們常需要對檔案進行壓縮,而不同的壓縮格式(如 Zip、Rar、7z 等)各有其優缺點。有時候我們希望能夠根據當下需求自由地切換壓縮方式,而不需要改動太多的程式碼。這時候策略模式 Strategy Pattern 就可以幫我們輕鬆實現這個需求。

什麼是策略模式?

策略模式是一種行為設計模式,它可以讓我們定義一系列的演算法,將每個演算法封裝起來,並讓它們可以互相替換使用。這樣一來程式碼不僅更加靈活,也更容易擴展跟維護了。

簡單來說,策略模式就是讓程式可以隨意更換的「策略」,讓程式能夠靈活地應對不同種的情況。

策略模式在壓縮器中的應用

假設你正在開發一個檔案壓縮的功能。一開始你可能只支援 ZIP 格式壓縮。但隨著使用者需求的增加,你發現需要添加 RAR、7Z 等其他壓縮格式的支援。

你的程式碼可能會寫成這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Compressor {
public:
void compress(const std::string& filename, const std::string& format) {
if (format == "zip") {
// ZIP 壓縮邏輯
} else if (format == "rar") {
// RAR 壓縮邏輯
} else if (format == "7z") {
// 7Z 壓縮邏輯
} else {
throw std::runtime_error("不支援的格式");
}
}
};

這種方法的問題在於每次新增新的壓縮格式時,都需要修改 Compressor 類別。這違反了「開放封閉原則」,也就是軟體應該對擴展開放,對修改封閉。

讓我們看看如何使用策略模式來改進這個設計:

我們先定義一個壓縮策略介面 CompressionStrategy,

1
2
3
4
5
class CompressionStrategy {
public:
virtual void compress(const std::string& filename) = 0;
virtual ~CompressionStrategy() = default;
};

然後為每種壓縮格式實作具體的策略,分別為 ZipStrategy、RarStrategy、SevenZipStrategy,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class ZipStrategy : public CompressionStrategy {
public:
void compress(const std::string& filename) override {
std::cout << "使用 ZIP 壓縮 " << filename << " 檔案\n";
}
};

class RarStrategy : public CompressionStrategy {
public:
void compress(const std::string& filename) override {
std::cout << "使用 RAR 壓縮 " << filename << " 檔案\n";
}
};

class SevenZipStrategy : public CompressionStrategy {
public:
void compress(const std::string& filename) override {
std::cout << "使用 7Z 壓縮 " << filename << " 檔案\n";
}
};

根據此情境在設計時,建立一個 Compressor 壓縮器,又為稱上下文類別,這個 Compressor 類別可以根據需求動態選擇不同的壓縮策略。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Compressor {
private:
std::unique_ptr<CompressionStrategy> strategy;

public:
Compressor(std::unique_ptr<CompressionStrategy> strategy)
: strategy(std::move(strategy)) {}

void setStrategy(std::unique_ptr<CompressionStrategy> newStrategy) {
strategy = std::move(newStrategy);
}

void compress(const std::string& filename) {
strategy->compress(filename);
}
};

當需要使用壓縮器時,可以這樣寫,Compressor 將會執行已經選擇的壓縮策略進行壓縮,然後也可以執行期間更換壓縮策略,

1
2
3
4
5
6
7
8
9
int main() {
Compressor compressor(std::make_unique<ZipStrategy>());
compressor.compress("file1.txt"); // 輸出:使用 ZIP 壓縮 file1.txt 檔案

compressor.setStrategy(std::make_unique<SevenZipStrategy>());
compressor.compress("file2.txt"); // 輸出:使用 7Z 壓縮 file2.txt 檔案

return 0;
}

策略模式的優點

使用策略模式,讓我們能夠方便地擴展壓縮器的功能,當需要增加新的壓縮格式時,只需新增一個實作了 CompressionStrategy 介面,並將其設定到 Compressor 中即可,完全不需要修改現有 Compressor 與其它壓縮策略的程式碼。另外策略模式還能讓程式碼變得更加清晰易懂,避免大量的條件判斷或分支邏輯,使系統在面對複雜業務需求時,依然能保持穩定和易於維護。

總結

策略模式是一個很實用的設計模式,能夠有效解決系統中某些功能需要頻繁變動或擴展的問題。在這個壓縮器範例中,我們看到如何使用策略模式來靈活地切換壓縮格式,並保持程式碼的清晰和可維護性。並能在日後的開發中靈活運用它,讓你的程式碼更加優雅。

C++ 設計模式入門:什麼是設計模式?為什麼要學習它們?

設計模式入門:什麼是設計模式?為什麼要學習它們?

當聽到「設計模式」這個詞時,可能會覺得這是什麼複雜寫程式的技術或者高深的專業知識。但實際上設計模式是一種能讓我們能夠寫出更好、更靈活程式的一套方法,不是專屬於高手的工具,反而是所有開發者都應該掌握的基礎。

什麼是設計模式?

設計模式其實是一組解決特定問題的經驗法則和最佳實踐。它們就像是軟體設計中的藍圖,你可以用它們來解決程式碼中反復出現的設計問題。換句話說,設計模式不是要讓你重新發明輪子,而是告訴你輪子怎麼樣做才能又快又穩。

假如你正在建造一座房子。你不會每次都從零開始設計門或窗戶對吧?你會使用已經被證明有效的設計。設計模式在軟體開發中的作用就像這些可重用的建築元素。

為什麼要學習設計模式?

學習設計模式的目的不僅僅是為了寫出漂亮的程式碼或者通過面試,更重要的是它能讓你在面對複雜問題時,有一套成熟的方法來應對。

你可能會問:「為什麼不直接寫程式呢?為什麼要花時間學習這些理論?」原因在於,當你寫程式寫得越久,你會發現自己常常面對相似的問題。如果每次都從零開始解決這些問題,不僅耗時還容易出錯。而設計模式正是經過專家長久時間驗證淬鍊的解決方案,能幫助你更快地找到正確的方向。

學習設計模式有以下幾點好處:

  1. 提高程式碼質量:設計模式提供了經過時間考驗的解決方案,可以幫助你寫出更清晰、更容易維護的程式碼。
  2. 加快開發速度:一旦你熟悉了常見的設計模式,你就可以更快識別問題並實作解決方案,而不是每次都重新造輪子。
  3. 促進團隊合作:為開發者提供了一種共同語言。當你說『我們這裡可以用觀察者模式』時,懂設計模式的同事馬上就能了解你的意思。
  4. 應對軟體變化:好的設計模式能讓你的程式碼更容易適應變化。在軟體開發中,變化是唯一不變的東西!
  5. 學習優秀的實踐設計:學習設計模式不僅是學習具體的解決方案,更是學習如何思考和解決問題。

讓我們開始掌握設計模式,成為一個更有智慧的開發者吧。

建立行模式(5)

結構型模式(7)

行為模式(11)

變化版

PHP 中的 Session 用途與實踐範例:完整指南

本篇 ShengYu 介紹 PHP 中的 Session 用法與範例,在當今的網路應用程式中,會話管理是一個關鍵組成部分。PHP 中的 $_SESSION 是一個強大的工具,讓開發者可以在不同的網頁之間儲存和共享使用者資料。本指南將詳細介紹 PHP 中的會話用途及實踐範例,幫助您在項目中有效使用會話。

什麼是 PHP 中的 Session?

會話(Session)是一個臨時的資料儲存機制,用於在使用者瀏覽不同的網頁時,保持使用者資料的持久性。在 PHP 中,$_SESSION 是一個超全域陣列,用於儲存會話資料。會話資料儲存在伺服器上,而使用者端則透過一個唯一的會話 ID 來識別。

會話的主要用途

  1. 保持使用者登入狀態:當使用者登錄到一個網站時,會話可以保存使用者的登入狀態,這樣在使用者瀏覽不同頁面時不需要重新登錄。
  2. 保存使用者首選項:會話可以保存使用者的設定和首選項,比如語言選擇、顏色主題等。
  3. 暫存表單資料:在多步驟表單中,可以使用會話來保存每一步的資料,直到使用者完成所有步驟。
  4. 購物車:在電子商務網站中,會話可以用來保存使用者的購物車內容,直到使用者結帳。

如何使用 PHP 中的 Session

1. 開始會話

在使用會話之前,需要先啟動會話。這通常是在每個頁面的開頭進行的:

1
2
3
<?php
session_start();
?>

2. 設定會話變數

可以將資料儲存到會話中,透過給 $_SESSION 陣列賦值:

1
2
3
4
5
<?php
session_start();
$_SESSION['username'] = 'JohnDoe';
$_SESSION['email'] = 'john.doe@example.com';
?>

3. 讀取會話變數

在需要使用會話資料的地方,可以讀取 $_SESSION 陣列中的值:

1
2
3
4
5
<?php
session_start();
echo 'Username: ' . $_SESSION['username']; // 輸出:Username: JohnDoe
echo 'Email: ' . $_SESSION['email']; // 輸出:Email: john.doe@example.com
?>

4. 刪除會話變數

可以使用 unset() 函式來刪除會話中的某個變數:

1
2
3
4
<?php
session_start();
unset($_SESSION['email']);
?>

5. 銷毀會話

如果需要刪除所有會話資料並結束會話,可以使用 session_destroy() 函式:

1
2
3
4
<?php
session_start();
session_destroy();
?>

範例:簡單的登入系統

以下是一個簡單的登入系統範例,使用會話來保存和檢查使用者的登入狀態。

login.php

這個頁面包含一個基本的登入表單。當使用者送出表單時,會檢查使用者名和密碼是否對應,如果對應,則設定會話變數並重導向到歡迎頁面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$username = $_POST['username'];
$password = $_POST['password'];

// 假設使用簡單的硬編碼認證
if ($username == 'admin' && $password == 'password') {
$_SESSION['loggedin'] = true;
$_SESSION['username'] = $username;
header('Location: welcome.php');
exit;
} else {
$error = 'Invalid username or password';
}
}
?>
<!DOCTYPE html>
<html>
<body>
<form method="POST">
Username: <input type="text" name="username" required><br>
Password: <input type="password" name="password" required><br>
<input type="submit" value="Login">
</form>
<?php if (isset($error)) echo $error; ?>
</body>
</html>

welcome.php

這個頁面是使用者登入後的歡迎頁面。如果使用者沒有登入,會重導向回登入頁面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
session_start();
if (!isset($_SESSION['loggedin'])) {
header('Location: login.php');
exit;
}
?>
<!DOCTYPE html>
<html>
<body>
<h1>Welcome, <?php echo $_SESSION['username']; ?>!</h1>
<a href="logout.php">Logout</a>
</body>
</html>

logout.php

這個頁面用於使用者登出,銷毀會話並重導向回登入頁面。

1
2
3
4
5
6
<?php
session_start();
session_destroy();
header('Location: login.php');
exit;
?>

結論

PHP 中的會話功能是一個強大且靈活的工具,能夠在不同頁面之間共享資料,實現使用者狀態保持、資料儲存和跨頁面資料共享。透過上面的範例,您可以看到如何在您的應用程式中實現會話管理。

以上就是 PHP Session 用途與實踐範例介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它相關文章推薦
如果你想學習 PHP 相關技術,可以參考看看下面的文章,
PHP 和 PDO 進行資料庫操作
PHP $_POST 變數用途、語法與實用範例詳解
深入理解 PHP 中的 isset 用法、範例及最佳實踐
PHP substr 函式全面解析與應用範例

PHP $_POST 變數用途、語法與實用範例詳解

本篇 ShengYu 介紹 PHP substr 用法與範例,在現代的網頁開發中,表單資料的處理是非常常見的需求之一。PHP 提供了許多方便的方法來處理表單資料,其中 _POST 超全域變數尤為重要。這篇文章將詳細介紹 PHP 的 _POST 變數,包括其用途、語法和多個實用範例,幫助開發者更好地理解和應用這個功能。

什麼是 _POST 變數?

_POST 是 PHP 中的超全域變數(superglobal),用來收集透過 HTTP POST 方法送出的表單資料。當使用者送出表單後,表單資料會被儲存在 _POST 變數中,並可以在伺服器端進行訪問和處理。這種方法通常用於需要保密或較大資料量的表單送出,例如使用者登錄、註冊和檔案上傳。

$_POST 的主要用途

  1. 表單資料接收:用於處理表單送出時傳遞的資料,例如使用者註冊、登錄表單等。
  2. 檔案上傳:用於處理檔案上傳時傳遞的資料。
  3. 安全性:相比 GET 方法,POST 方法不會將資料顯示在 URL 中,因此更適合傳遞敏感資訊(例如密碼)。

_POST 變數的使用方法

要使用 _POST 變數,首先需要建立一個使用 POST 方法送出的 HTML 表單。然後,在 PHP 腳本中訪問 _POST 變數來處理送出的資料。

範例一:簡單表單處理

以下是一個簡單的例子,展示如何使用 $_POST 接收和處理來自表單的資料。
首先,我們建立一個簡單的 HTML 表單,讓使用者輸入名字和電子郵件地址。

HTML 表單:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>POST 表單範例</title>
</head>
<body>
<form action="process_form.php" method="post">
<label for="name">名字:</label>
<input type="text" id="name" name="name"><br>
<label for="email">電子郵件:</label>
<input type="email" id="email" name="email"><br>
<input type="submit" value="送出">
</form>
</body>
</html>

PHP 腳本 (process_form.php):

1
2
3
4
5
6
7
8
9
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$name = $_POST['name'];
$email = $_POST['email'];

echo "名字: " . htmlspecialchars($name) . "<br>";
echo "電子郵件: " . htmlspecialchars($email);
}
?>

在這個範例中,使用者送出表單後,資料會被發送到 process_form.php。PHP 腳本檢查請求方法是否為 POST,然後透過 _POST 變數訪問表單資料,並使用 htmlspecialchars 函式進行輸出,防止 XSS 攻擊。

範例二:帶有驗證的表單處理

除了基本的表單處理,我們還可以新增一些資料驗證來確保送出的資料是有效的。

HTML 表單:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>帶驗證的 POST 表單</title>
</head>
<body>
<form action="process_form_with_validation.php" method="post">
<label for="name">名字:</label>
<input type="text" id="name" name="name"><br>
<label for="email">電子郵件:</label>
<input type="email" id="email" name="email"><br>
<input type="submit" value="送出">
</form>
</body>
</html>

PHP 腳本 (process_form_with_validation.php):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?php
$name = $email = "";
$nameErr = $emailErr = "";

if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST['name'])) {
$nameErr = "名字是必填項";
} else {
$name = test_input($_POST['name']);
}

if (empty($_POST['email'])) {
$emailErr = "電子郵件是必填項";
} else {
$email = test_input($_POST['email']);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailErr = "無效的電子郵件格式";
}
}
}

function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>表單結果</title>
</head>
<body>
<h2>表單驗證結果</h2>
<p><span class="error">* 必填字段</span></p>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
<label for="name">名字:</label>
<input type="text" id="name" name="name" value="<?php echo $name;?>">
<span class="error">* <?php echo $nameErr;?></span>
<br><br>
<label for="email">電子郵件:</label>
<input type="email" id="email" name="email" value="<?php echo $email;?>">
<span class="error">* <?php echo $emailErr;?></span>
<br><br>
<input type="submit" value="送出">
</form>

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST" && $nameErr == "" && $emailErr == "") {
echo "<h3>表單資料已送出成功</h3>";
echo "名字: " . $name . "<br>";
echo "電子郵件: " . $email;
}
?>
</body>
</html>

在這個範例中,我們新增了基本的資料驗證。test_input 函式對輸入資料進行處理,防止注入攻擊和 XSS 攻擊。表單送出後,資料會被檢查,如果有錯誤,錯誤資訊會顯示在表單旁邊。只有當所有字段都正確填寫時,表單資料才會被顯示。

為什麼要使用 $_POST

保護資料隱私

相比 GET 方法,POST 方法不會將資料顯示在 URL 中,因此更適合傳遞敏感資訊。例如,當使用者送出包含密碼的表單時,使用 POST 方法可以避免密碼在 URL 中曝光。

傳輸大資料量

POST 方法沒有 GET 方法的 URL 長度限制,這意味著我們可以使用 POST 方法來傳輸更大的資料量,例如檔案上傳。

安全性考量

使用 $_POST 處理表單資料時,我們需要注意以下幾點,以確保資料的安全:

  1. 資料驗證:對接收到的資料進行驗證,確保資料符合預期。例如,檢查電子郵件地址是否有效。
  2. 資料消毒:使用 htmlspecialchars 或其他合適的函式來消毒資料,防止 XSS 攻擊。
  3. SQL 注入防護:如果將資料儲存到資料庫中,應使用預處理語句或其他方法防止 SQL 注入。

結論

_POST 變數是 PHP 中一個非常重要的工具,用於收集和處理來自 HTML 表單的資料。透過理解其基本用法和結合資料驗證技術,我們可以更安全有效地處理使用者輸入的資料。

希望這篇文章能幫助你更好地理解 PHP $_POST 變數的用途和實踐方式。
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它相關文章推薦
如果你想學習 PHP 相關技術,可以參考看看下面的文章,
PHP 和 PDO 進行資料庫操作
PHP 中的 Session 用途與實踐範例:完整指南
PHP substr 函式全面解析與應用範例
深入理解 PHP 中的 isset 用法、範例及最佳實踐
了解 PHP 中的 session_start() 函式用途與範例

PHP substr 函式全面解析與應用範例

本篇 ShengYu 介紹 PHP substr 用法與範例,在開發 PHP 應用程式的過程中,字串處理是一個非常常見的需求。無論是提取使用者輸入的一部分資料,還是展示文章的部分內容,這些操作都離不開字串處理函式。而在眾多的 PHP 字串處理函式中,substr 函式是一個非常實用的工具。本篇文章將深入解析 PHP substr 函式的用途及其應用範例,幫助開發者更好地理解和運用這個函式。

什麼是 PHP substr 函式?

substr 函式的全稱是 “substring”,即從一個字串中提取子串。它能夠根據指定的起始位置和長度,從原始字串中截取出所需的部分,並回傳這個子串。這個函式的使用頻率非常高,尤其是在處理使用者輸入、產生摘要或顯示部分內容時,substr 都能發揮重要作用。

PHP substr 函式的語法

在開始探討具體的應用範例之前,我們先來看一下 substr 函式的語法:

1
substr(string $string, int $start, int $length = ?): string
  • $string:要處理的原始字串。
  • $start:開始截取的位置,從 0 開始。如果是負數,表示從字串末尾開始計算的位置。
  • $length(可選):截取的長度。如果未提供或為 null,則一直截取到字串末尾。如果是負數,表示到字串末尾之前的字元數。

PHP substr 函式的應用範例

為了讓大家更好地理解 substr 函式的用法,我們將透過一些具體的例子來進行說明。

範例 1:基本用法

假設我們有一個字串 “Hello, World!”,我們希望從中截取出 “World” 這個子串。可以這樣寫:

1
2
3
$text = "Hello, World!";
$substring = substr($text, 7, 5); // 從位置 7 開始,截取 5 個字元
echo $substring; // 輸出 "World"

在這個例子中,我們從字串的第 7 個位置開始,截取 5 個字元,結果得到了 “World”。

範例 2:從字串末尾開始計算

如果我們希望從字串的末尾開始計算位置,同樣可以使用 substr 函式。以下是具體用法:

1
2
3
$text = "Hello, World!";
$substring = substr($text, -6, 5); // 從倒數第 6 個字元開始,截取 5 個字元
echo $substring; // 輸出 "World"

在這裡,我們從倒數第 6 個字元開始,截取 5 個字元,結果同樣是 “World”。

範例 3:省略長度參數

如果我們希望從某個位置開始,一直截取到字串末尾,可以省略長度參數:

1
2
3
$text = "Hello, World!";
$substring = substr($text, 7); // 從位置 7 開始,一直截取到字串末尾
echo $substring; // 輸出 "World!"

這樣寫可以確保從第 7 個位置開始,將剩餘的字串全部截取出來。

範例 4:使用負數長度

substr 函式還支持負數長度,表示從開始位置到字串末尾之前的字元數:

1
2
3
$text = "Hello, World!";
$substring = substr($text, 0, -7); // 從位置 0 開始,截取到倒數第 7 個字元之前
echo $substring; // 輸出 "Hello"

在這個例子中,我們從位置 0 開始,截取到倒數第 7 個字元之前,結果得到了 “Hello”。

範例 5:長度超過字串長度

當長度參數超過了字串本身的長度時,substr 函式會自動截取到字串末尾:

1
2
3
$text = "Hello";
$substring = substr($text, 2, 10); // 長度參數超過了字串長度
echo $substring; // 輸出 "llo"(從位置 2 開始,一直截取到字串末尾)

在這裡,我們從位置 2 開始截取,儘管指定的長度為 10,但實際只截取到字串末尾,結果為 “llo”。

範例 6:開始位置超過字串長度

如果開始位置超過了字串的長度,substr 會回傳一個空字串:

1
2
3
$text = "Hello";
$substring = substr($text, 10); // 開始位置超過字串長度
echo $substring; // 輸出 ""(空字串)

在這個例子中,開始位置超過了字串的長度,結果回傳了一個空字串。

注意事項

在使用 substr 函式時,有幾點需要特別注意:

  • 負數開始位置:如果 $start 是負數,表示從字串末尾開始計算的位置。
  • 負數長度:如果 $length 是負數,表示到字串末尾之前的字元數。
  • 開始位置超過字串長度:如果 $start 超過了字串長度,將回傳一個空字串。
  • 長度超過字串長度:如果 $length 超過了剩餘的字元數,將截取到字串末尾。

結語

PHP 的 substr 函式是處理字串時的一個強大工具,透過靈活運用它的各種參數,可以實現多種字串操作需求。無論是在截取使用者輸入的一部分資料,還是產生文章摘要,substr 函式都能夠提供高效的解決方案。

希望這篇文章能幫助你更好地理解 PHP substr 的用途和實踐方式。
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它相關文章推薦
如果你想學習 PHP 相關技術,可以參考看看下面的文章,
PHP str_pad 函式用途、語法與實用範例解析
PHP 和 PDO 進行資料庫操作
深入理解 PHP 中的 isset 用法、範例及最佳實踐
了解 PHP 中的 session_start() 函式用途與範例

PHP str_pad 函式用途、語法與實用範例解析

本篇 ShengYu 介紹 PHP str_pad 用法與範例,在現代的網頁開發中,處理和格式化字串是常見且重要的操作之一。PHP 提供了許多強大的字串處理函式,其中 str_pad 函式尤為實用。這篇文章將詳細介紹 PHP 的 str_pad 函式,包括其用途、語法和多個實用範例,幫助開發者更好地理解和應用這個功能。

什麼是 str_pad 函式?

str_pad 是 PHP 中用來對字串進行填充的函式。它可以在字串的左邊、右邊或兩邊填充指定的字元,使字串達到預定的長度。這在格式化輸出、對齊文字和產生報表時非常有用。例如,在需要產生統一寬度的資料表格時,我們可以利用 str_pad 函式來確保每個欄位都具有相同的寬度,從而使表格更加整齊和易於閱讀。

str_pad 函式的語法

str_pad 函式的語法如下:

1
str_pad(string $input, int $pad_length, string $pad_string = " ", int $pad_type = STR_PAD_RIGHT): string

這裡我們來逐一解釋各個參數的含義:

  • $input: 要填充的原始字串。
  • $pad_length: 填充後的總長度。如果指定的長度小於或等於原始字串的長度,則不會進行填充。
  • $pad_string: 用來填充的字串。預設為一個空格字元。
  • $pad_type: 填充類型,可以是以下三種之一:
    • STR_PAD_RIGHT(預設):在字串的右邊填充。
    • STR_PAD_LEFT:在字串的左邊填充。
    • STR_PAD_BOTH:在字串的兩邊填充。

str_pad 函式的使用範例

以下是幾個常見的 str_pad 函式使用範例,展示了如何根據不同需求對字串進行填充。

範例一:右邊填充

在這個範例中,我們將字串的右邊填充指定的字元,使其達到預定的長度。

1
2
3
4
5
<?php
$input = "Hello";
$padded = str_pad($input, 10, "-");
echo $padded; // 輸出 "Hello-----"
?>

在這裡,原始字串 “Hello” 被填充了 5 個 “-“ 號,最終達到了 10 個字元的長度。

範例二:左邊填充

有時候我們需要在字串的左邊進行填充。下面的範例展示了如何實現這一點。

1
2
3
4
5
<?php
$input = "Hello";
$padded = str_pad($input, 10, "-", STR_PAD_LEFT);
echo $padded; // 輸出 "-----Hello"
?>

這次,字串 “Hello” 的左邊被填充了 5 個 “-“ 號。

範例三:兩邊填充

如果需要在字串的兩邊同時進行填充,可以使用 STR_PAD_BOTH 參數。這個範例展示了這種用法。

1
2
3
4
5
<?php
$input = "Hello";
$padded = str_pad($input, 10, "-", STR_PAD_BOTH);
echo $padded; // 輸出 "--Hello---"(注意:左右填充字元數可能不完全相等)
?>

在這範例裡,字串 “Hello” 被填充在兩邊,但由於總長度為 10,左右兩邊的填充字元數可能不完全相等。

範例四:使用多字元填充

str_pad 函式不僅可以使用單個字元來填充,還可以使用多個字元。下面的範例展示了如何使用多字元填充。

1
2
3
4
5
<?php
$input = "Hello";
$padded = str_pad($input, 10, "123");
echo $padded; // 輸出 "Hello12312"
?>

在這裡,填充字串 “123” 被重複使用,直到原始字串達到指定的長度 10。

範例五:格式化數字

在處理數字格式時,str_pad 也非常有用。例如,當我們需要統一顯示數字的位數時,可以使用 str_pad 進行左側填充。

1
2
3
4
5
<?php
$number = 7;
$formattedNumber = str_pad($number, 5, "0", STR_PAD_LEFT);
echo $formattedNumber; // 輸出 "00007"
?>

在這個範例中,數字 7 被填充了四個 “0”,使其總長度達到 5 位,便於對齊和顯示。

為什麼 str_pad 函式這麼重要?

str_pad 函式在許多情況下都非常實用,特別是在需要格式化和對齊文字時。例如:

  1. 產生報表:在產生報表時,我們常常需要對齊各個欄位的資料,使得報表更加美觀和易於閱讀。
  2. 格式化輸出:在終端或控制台輸出中,格式化的輸出能夠使資料更加清晰明瞭。
  3. 處理固定寬度檔案:在處理一些固定寬度的檔案(如某些舊式資料格式)時,我們需要確保每個欄位都具有固定的寬度。

結論

str_pad 函式是 PHP 中一個非常強大且靈活的工具,能夠幫助我們輕鬆地對字串進行填充和格式化。無論是在產生報表、格式化輸出還是處理固定寬度檔案時,str_pad 都能發揮重要作用。透過理解其語法和各種填充模式,我們可以根據不同的需求靈活應用這個函式,從而提高程式碼的可讀性和可維護性。

希望這篇文章能夠幫助你更好地理解和使用 str_pad 函式。以上就是我們對 PHP str_pad 函式的全面解析。
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它相關文章推薦
如果你想學習 PHP 相關技術,可以參考看看下面的文章,
PHP substr 函式全面解析與應用範例
PHP 和 PDO 進行資料庫操作
PHP 執行發生錯誤在 Chrome/Firefox 上顯示 Error 500,要怎麼讓 PHP 顯示錯誤
深入理解 PHP 中的 isset 用法、範例及最佳實踐
了解 PHP 中的 session_start() 函式用途與範例

如何使用 PHP 的 uniqid 函式產生唯一ID並提高應用程式安全性

本篇 ShengYu 介紹 PHP uniqid 用法與範例,在現代Web開發中,唯一ID產生是一項非常常見的需求,無論是用於使用者帳號、訂單號還是其他標識符。PHP 提供了一個非常方便的內置函式 uniqid(),能夠根據當前時間戳產生一個唯一ID。在這篇文章中,我們將詳細介紹 uniqid() 函式的使用方法,以及如何進一步提高ID的唯一性和安全性。

什麼是 uniqid() 函式?

uniqid() 是 PHP 中的一個內置函式,用於產生基於當前時間微秒數的唯一ID。該函式的基本用法非常簡單:

1
2
$id = uniqid();
echo $id;

這段程式碼將產生一個類似於 5f2c912cd6d88 的字串,其中包含13個字元。產生的ID基於當前的時間戳,精確到微秒。這意味著,在通常情況下,每次呼叫 uniqid() 都會產生一個不同的ID。

uniqid() 的可選參數

uniqid() 函式有兩個可選參數:

  1. $prefix:一個可選的字串參數,新增到產生的唯一ID之前。
  2. $more_entropy:一個布爾值(預設為 false)。如果設定為 true,將附加更多的熵(隨機性)以進一步提高唯一性。

讓我們看看這些參數如何影響 uniqid() 函式的輸出。

uniqid() 帶前綴的使用方法

有時候,我們可能希望產生的唯一ID包含某些前綴,以便於區分不同類型的ID。例如,可以為使用者ID新增前綴“user_”:

1
2
3
$prefix = 'user_';
$id = uniqid($prefix);
echo $id;

這將產生一個類似於 user_5f2c912cd6d88 的字串。這樣的ID不僅唯一,還能透過前綴快速識別其用途。

uniqid() 增加熵的使用方法

在高併發環境下,僅僅依賴時間戳可能不足以保證唯一性。此時,我們可以透過設定 $more_entropy 參數來增加ID的熵(隨機性):

1
2
$id = uniqid('', true);
echo $id;

這將產生一個更長、更複雜的唯一ID,例如 5f2c912cd6d88.66138147。這樣的ID在高併發環境下的唯一性更高。

uniqid() 綜合使用方法

當我們既需要前綴又需要增加熵時,可以同時使用兩個參數:

1
2
3
$prefix = 'order_';
$id = uniqid($prefix, true);
echo $id;

這將產生一個帶前綴和更多熵的唯一ID,例如 order_5f2c912cd6d88.66138147

uniqid() 提高唯一性和安全性

雖然 uniqid() 能產生基於時間戳的唯一ID,但在某些高並發環境下,產生的ID仍有可能重複。如果需要更高的唯一性和安全性,我們可以結合其他方法,如使用 md5()sha1(),甚至 PHP 的隨機位元組產生函式 random_bytes()

例如:

1
2
$id = md5(uniqid(rand(), true));
echo $id;

這將產生一個32字元長的唯一ID,例如 e7d1bc78bafb0dbd8c43f8d3fba95025。這種方法透過混合隨機數和時間戳,並使用 md5() 哈希函式,極大地提高了ID的唯一性和不可預測性。

使用 random_bytes() 產生高安全性ID

如果應用場景需要極高的安全性(例如加密密鑰或重要資料標識符),可以使用 PHP 的 random_bytes() 函式來產生高安全性的隨機位元組,然後將其轉換為十六進位字串:

1
2
$id = bin2hex(random_bytes(16));
echo $id;

這將產生一個32字元長的隨機ID,例如 4e5d6c9a2b3f4d7e8f9a1b2c3d4e5f6arandom_bytes() 函式使用作業系統的隨機數產生器,保證了隨機性的質量。

結論

PHP 的 uniqid() 函式是一個方便且易於使用的工具,適用於多種需要唯一標識符的場景。透過適當使用其可選參數,我們可以在大多數應用中產生足夠唯一的ID。然而,在高並發或安全需求更高的情況下,建議結合其他隨機數產生方法以進一步提高ID的唯一性和安全性。透過這些方法,我們可以確保應用程式的穩定性和安全性,滿足各種業務需求。

希望這篇文章能幫助你更好地理解 PHP uniqid 的用途和實踐方式。
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它相關文章推薦
如果你想學習 PHP 相關技術,可以參考看看下面的文章,
PHP substr 函式全面解析與應用範例
PHP str_pad 函式用途、語法與實用範例解析
PHP 和 PDO 進行資料庫操作
深入理解 PHP 中的 isset 用法、範例及最佳實踐
了解 PHP 中的 session_start() 函式用途與範例

Ubuntu 下安裝 wordpress

本篇 ShengYu 紀錄在 Ubuntu 下安裝 wordpress,我自己是用 Ubuntu 22.04 安裝 wordpress 6.5.5。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
sudo apt update

sudo apt install php libapache2-mod-php php-mysql \
php-curl php-gd php-xml php-mbstring php-xmlrpc \
php-zip php-soap php-intl -y

# ubuntu 官網
sudo apt install apache2 \
ghostscript \
libapache2-mod-php \
mysql-server \
php \
php-bcmath \
php-curl \
php-imagick \
php-intl \
php-json \
php-mbstring \
php-mysql \
php-xml \
php-zip

下載wordpress-6.5.5版

1
2
3
wget https://tw.wordpress.org/wordpress-6.5.5-zh_TW.zip
sudo unzip wordpress-6.5.5-zh_TW.zip -d /var/www/html
sudo chown -R www-data:www-data /var/www/html/wordpress/

或者下載最新版

1
2
3
wget https://tw.wordpress.org/latest-zh_TW.zip
sudo unzip latest-zh_TW.zip -d /var/www/html
sudo chown -R www-data:www-data /var/www/html/wordpress/

新建資料庫

1
2
3
4
5
6
sudo mysql
CREATE DATABASE wordpress;
CREATE USER 'wordpressuser'@'localhost' IDENTIFIED BY 'your-password';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpressuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;

編輯 wordpress.conf
sudo vim /etc/apache2/sites-available/wordpress.conf

1
2
3
<Directory /var/www/html/wordpress/>
AllowOverride All
</Directory>

重啟 apache

1
2
3
sudo a2ensite wordpress.conf
sudo a2enmod rewrite
sudo systemctl restart apache2

開啟網頁,填上剛剛稍早設定的資料,按下安裝,搞定!
資料庫名稱 wordpress
使用者名稱 wordpressuser
密碼 your-password

以上就是 Ubuntu 下安裝 wordpress 筆記,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其他參考
安裝 WordPress – 如何在 Ubuntu 上安裝 WordPress
ubuntu官網Install and configure WordPress

其它相關文章推薦
macOS 下使用 rm 指令如何避免誤刪除

深入理解 PHP 中的 isset 用法、範例及最佳實踐

本篇 ShengYu 介紹 PHP isset 用法與範例,在PHP編程中,isset 是 PHP 內建的函式,它用於檢查變數是否已設定且其值不為 null。了解和正確使用 isset 對於避免未定義變數錯誤和提高程式碼穩定性至關重要。本文將詳細介紹 isset 的用途、語法,並透過多個範例展示其在不同場景中的應用。

isset 的用途

isset 函式主要用於以下幾個方面:

  1. 檢查表單送出中的變數是否存在:這有助於避免在處理使用者送出的表單資料時遇到未定義變數的錯誤。
  2. 檢查陣列中的key是否存在:在處理陣列資料時,這樣做可以確保某個key確實存在並且有值。
  3. 檢查物件屬性是否已設定:這在面向物件編程中尤為重要,用來確保某個屬性已經被初始化。

isset 的語法

1
bool isset(mixed $var, mixed ...$vars)
  • $var:要檢查的變數。
  • $vars:可選的額外變數,可以一次檢查多個變數。

isset 的基本用法

下面是一個基本的 isset 使用範例,展示了如何檢查單個變數是否被設定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$var1 = "Hello, World!";
$var2 = null;

if (isset($var1)) {
echo '$var1 is set and not null';
} else {
echo '$var1 is not set or is null';
}
// 輸出:$var1 is set and not null

if (isset($var2)) {
echo '$var2 is set and not null';
} else {
echo '$var2 is not set or is null';
}
// 輸出:$var2 is not set or is null

在這個範例中,$var1 被設定為一個字串,因此 isset($var1) 回傳 true,而 $var2 被設定為 null,因此 isset($var2) 回傳 false

檢查陣列key

使用 isset 可以方便地檢查陣列中的某個key是否存在:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$array = array('key1' => 'value1', 'key2' => 'value2');

if (isset($array['key1'])) {
echo '$array["key1"] is set and not null';
} else {
echo '$array["key1"] is not set or is null';
}
// 輸出:$array["key1"] is set and not null

if (isset($array['key3'])) {
echo '$array["key3"] is set and not null';
} else {
echo '$array["key3"] is not set or is null';
}
// 輸出:$array["key3"] is not set or is null

這裡展示了如何檢查陣列中某個key是否存在。$array['key1'] 存在且有值,因此 isset($array['key1']) 回傳 true。而 $array['key3'] 不存在,因此 isset($array['key3']) 回傳 false

一次檢查多個變數

isset 可以一次檢查多個變數,只要其中任何一個變數未設定或為 null,就會回傳 false

1
2
3
4
5
6
7
8
9
10
$var1 = "Hello";
$var2 = "World";
$var3 = null;

if (isset($var1, $var2, $var3)) {
echo 'All variables are set and not null';
} else {
echo 'One or more variables are not set or are null';
}
// 輸出:One or more variables are not set or are null

在這個範例中,雖然 $var1$var2 都被設定且不為 null,但 $var3null,因此 isset($var1, $var2, $var3) 回傳 false

檢查表單送出

在處理使用者送出的表單時,isset 可以用來檢查表單字段是否被設定,從而避免處理未定義變數的錯誤。假設我們有一個簡單的HTML表單:

1
2
3
4
5
<form method="post" action="process.php">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="Login">
</form>

process.php 中,我們可以使用 isset 來檢查表單字段是否被設定:

1
2
3
4
5
6
7
8
9
if (isset($_POST['username']) && isset($_POST['password'])) {
$username = $_POST['username'];
$password = $_POST['password'];
// 處理登錄邏輯
echo "Username: " . $username . "<br>";
echo "Password: " . $password;
} else {
echo "Please fill in both username and password.";
}

透過這種方式,我們可以確保使用者送出的 usernamepassword 字段已經被設定並且不為 null,從而避免處理未定義變數的錯誤。

總結

isset 是 PHP 中非常實用的函式,透過檢查變數是否被設定且不為 null,它幫助開發者避免了許多常見的錯誤。無論是在處理表單送出、檢查陣列key還是檢查物件屬性,isset 都能發揮重要作用。透過正確理解和使用 isset,我們可以編寫出更加健壯和可靠的PHP程式碼。

希望這篇文章能幫助你更好地理解 PHP isset 的用途和最佳實踐。
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它相關文章推薦
如果你想學習 PHP 相關技術,可以參考看看下面的文章,
PHP $_POST 變數用途、語法與實用範例詳解
PHP 中的 Session 用途與實踐範例:完整指南
PHP 和 PDO 進行資料庫操作
PHP 執行發生錯誤在 Chrome/Firefox 上顯示 Error 500,要怎麼讓 PHP 顯示錯誤
了解 PHP 中的 session_start() 函式用途與範例