Skip to content
เข้าสู่ระบบ

Functions


Functions เป็นบล็อกของโค้ดที่ทำงานเฉพาะอย่าง สามารถเรียกใช้ซ้ำได้ ในบทนี้เราจะเรียนรู้การสร้างและใช้งาน functions ใน PHP 8.4+


<?php
// Function พื้นฐาน
function sayHello() {
echo "Hello, World!";
}
sayHello(); // "Hello, World!"
// Function พร้อม return value
function getGreeting() {
return "Hello!";
}
$message = getGreeting();
echo $message; // "Hello!"
// Function พร้อม parameters
function greet($name) {
return "Hello, $name!";
}
echo greet("John"); // "Hello, John!"
// หลาย parameters
function add($a, $b) {
return $a + $b;
}
echo add(5, 3); // 8
<?php
// ชื่อ function ที่ถูกต้อง
function my_function() {} // snake_case
function myFunction() {} // camelCase (แนะนำ)
function _privateFunction() {} // ขึ้นต้นด้วย _
function function123() {} // มีตัวเลขได้
// ชื่อที่ผิด
// function 123function() {} // ขึ้นต้นด้วยตัวเลขไม่ได้
// function my-function() {} // ใช้ - ไม่ได้
// function names เป็น case-insensitive
function SayHi() {
echo "Hi!";
}
sayhi(); // ทำงานได้ (แต่ไม่แนะนำ)
SAYHI(); // ทำงานได้

<?php
function divide($a, $b) {
return $a / $b;
}
echo divide(10, 2); // 5
// divide(10); // Error: Too few arguments
<?php
function greet($name, $greeting = "Hello") {
return "$greeting, $name!";
}
echo greet("John"); // "Hello, John!"
echo greet("John", "Hi"); // "Hi, John!"
echo greet("John", "Welcome"); // "Welcome, John!"
// Default values ต้องอยู่หลัง required parameters
// ❌ ผิด
// function wrong($a = 1, $b) {} // Deprecated ใน PHP 8.0+
// ✅ ถูก
function correct($b, $a = 1) {}
<?php
// PHP 8.0+: Nullable types
function findUser(?int $id): ?array {
if ($id === null) {
return null;
}
return ["id" => $id, "name" => "User $id"];
}
findUser(1); // ["id" => 1, "name" => "User 1"]
findUser(null); // null
// Optional parameters (มี default)
function search(string $query, int $limit = 10): array {
// ค้นหา...
return [];
}
search("php"); // limit = 10
search("php", 20); // limit = 20
<?php
function createUser(
string $name,
string $email,
int $age = 18,
bool $isActive = true,
?string $avatar = null
) {
return compact('name', 'email', 'age', 'isActive', 'avatar');
}
// Positional arguments (วิธีเดิม)
$user = createUser("John", "john@example.com", 25, true, "avatar.jpg");
// Named arguments (PHP 8.0+)
$user = createUser(
name: "John",
email: "john@example.com",
age: 25,
isActive: true,
avatar: "avatar.jpg"
);
// ข้าม default parameters ได้
$user = createUser(
name: "Jane",
email: "jane@example.com",
avatar: "jane.jpg" // ข้าม age และ isActive
);
// สลับ order ได้
$user = createUser(
email: "bob@example.com",
name: "Bob"
);
// ผสม positional และ named (positional ต้องมาก่อน)
$user = createUser(
"Alice", // positional
email: "alice@example.com" // named
);
<?php
// รับ arguments ไม่จำกัดจำนวน
function sum(...$numbers) {
return array_sum($numbers);
}
echo sum(1, 2, 3); // 6
echo sum(1, 2, 3, 4, 5); // 15
echo sum(); // 0
// พร้อม type hint
function sumIntegers(int ...$numbers): int {
return array_sum($numbers);
}
// Variadic ต้องเป็น parameter สุดท้าย
function format(string $template, mixed ...$values): string {
return sprintf($template, ...$values);
}
echo format("Name: %s, Age: %d", "John", 25);
// "Name: John, Age: 25"
// Spread operator (กลับด้าน)
$numbers = [1, 2, 3, 4, 5];
echo sum(...$numbers); // 15
$args = ["John", 25];
echo format("Name: %s, Age: %d", ...$args);

<?php
// Return type declaration
function getAge(): int {
return 25;
}
function getName(): string {
return "John";
}
function isActive(): bool {
return true;
}
function getScores(): array {
return [85, 90, 78];
}
// Nullable return
function findById(int $id): ?string {
return $id > 0 ? "User $id" : null;
}
<?php
function parse(string $input): int|float {
return is_numeric($input)
? (strpos($input, '.') !== false ? (float)$input : (int)$input)
: 0;
}
echo parse("42"); // int(42)
echo parse("3.14"); // float(3.14)
<?php
// void - ไม่ return อะไร
function logMessage(string $message): void {
echo "[LOG] $message\n";
// return; // OK (implicit void)
// return null; // Error!
}
// never - ไม่ return (exit, throw, หรือ loop forever)
function redirect(string $url): never {
header("Location: $url");
exit;
}
function throwError(string $message): never {
throw new RuntimeException($message);
}
<?php
// mixed - ยอมรับทุก type (PHP 8.0+)
function log(mixed $data): void {
print_r($data);
}
// static - return instance ของ class ปัจจุบัน (late binding)
class Builder {
public static function create(): static {
return new static();
}
}
// self vs static
class ParentClass {
public static function createSelf(): self {
return new self();
}
public static function createStatic(): static {
return new static();
}
}
class ChildClass extends ParentClass {}
ChildClass::createSelf(); // ParentClass instance
ChildClass::createStatic(); // ChildClass instance

PHP สามารถบังคับ strict type checking:

<?php
// ไม่มี strict types (default)
function addNumbers(int $a, int $b): int {
return $a + $b;
}
echo addNumbers("5", "3"); // 8 (strings ถูกแปลงเป็น int)
// เปิด strict types (ต้องอยู่บรรทัดแรก)
declare(strict_types=1);
function addNumbersStrict(int $a, int $b): int {
return $a + $b;
}
echo addNumbersStrict(5, 3); // 8
// echo addNumbersStrict("5", "3"); // TypeError!

<?php
function myFunction() {
$localVar = "I'm local";
echo $localVar; // OK
}
myFunction();
// echo $localVar; // Error: undefined variable
<?php
$globalVar = "I'm global";
function myFunction() {
// ต้องใช้ global keyword
global $globalVar;
echo $globalVar; // "I'm global"
// หรือใช้ $GLOBALS
echo $GLOBALS['globalVar']; // "I'm global"
}
myFunction();
// ❌ ไม่แนะนำให้ใช้ global มาก
// ✅ ส่งผ่าน parameter แทน
function betterFunction(string $value) {
return $value;
}
<?php
function counter() {
static $count = 0; // เก็บค่าระหว่างการเรียก
return ++$count;
}
echo counter(); // 1
echo counter(); // 2
echo counter(); // 3
// ใช้สำหรับ caching
function fibonacci(int $n): int {
static $cache = [];
if ($n <= 1) return $n;
if (!isset($cache[$n])) {
$cache[$n] = fibonacci($n - 1) + fibonacci($n - 2);
}
return $cache[$n];
}

<?php
// Anonymous function
$greet = function($name) {
return "Hello, $name!";
};
echo $greet("John"); // "Hello, John!"
// ใช้เป็น callback
$numbers = [1, 2, 3, 4, 5];
$doubled = array_map(function($n) {
return $n * 2;
}, $numbers);
// [2, 4, 6, 8, 10]
// ใช้กับ usort
$users = [
["name" => "Charlie", "age" => 30],
["name" => "Alice", "age" => 25],
["name" => "Bob", "age" => 35],
];
usort($users, function($a, $b) {
return $a["age"] <=> $b["age"];
});
<?php
$prefix = "Mr.";
// ใช้ use เพื่อเข้าถึงตัวแปรจาก parent scope
$greet = function($name) use ($prefix) {
return "$prefix $name";
};
echo $greet("John"); // "Mr. John"
// ต้องการแก้ไขตัวแปร ใช้ &
$counter = 0;
$increment = function() use (&$counter) {
$counter++;
};
$increment();
$increment();
echo $counter; // 2
// Closure ใน loop
$functions = [];
for ($i = 0; $i < 3; $i++) {
$functions[] = function() use ($i) {
return $i;
};
}
echo $functions[0](); // 0
echo $functions[1](); // 1
echo $functions[2](); // 2

Arrow functions เป็น syntax สั้นสำหรับ closures:

<?php
// Closure แบบเดิม
$double = function($n) {
return $n * 2;
};
// Arrow function (PHP 7.4+)
$double = fn($n) => $n * 2;
echo $double(5); // 10
// Arrow function inherit scope โดยอัตโนมัติ (ไม่ต้อง use)
$multiplier = 3;
$multiply = fn($n) => $n * $multiplier;
echo $multiply(4); // 12
// ใช้กับ array functions
$numbers = [1, 2, 3, 4, 5];
$doubled = array_map(fn($n) => $n * 2, $numbers);
$evens = array_filter($numbers, fn($n) => $n % 2 === 0);
$sum = array_reduce($numbers, fn($acc, $n) => $acc + $n, 0);
// พร้อม type hints
$format = fn(int $n): string => "Number: $n";
// Multi-line (ต้องใช้ closure แบบเต็ม)
// Arrow function รองรับแค่ single expression
$process = function($data) {
$processed = transform($data);
validate($processed);
return $processed;
};

เปรียบเทียบ Closure vs Arrow Function

Section titled “เปรียบเทียบ Closure vs Arrow Function”
FeatureClosureArrow Function
Syntaxfunction($x) { return $x; }fn($x) → $x
Multi-line✅ ได้❌ ไม่ได้
Implicit return❌ ต้อง return✅ อัตโนมัติ
use keyword✅ ต้องใช้❌ ไม่ต้อง (auto)
Modify outer vars✅ use (&$var)❌ ไม่ได้

<?php
// สร้าง Closure จาก function/method
function multiply(int $a, int $b): int {
return $a * $b;
}
// PHP 8.1+: First-class callable syntax
$callable = multiply(...); // Closure from function
echo $callable(3, 4); // 12
// ใช้กับ methods
class Calculator {
public function add(int $a, int $b): int {
return $a + $b;
}
public static function subtract(int $a, int $b): int {
return $a - $b;
}
}
$calc = new Calculator();
$addMethod = $calc->add(...);
echo $addMethod(5, 3); // 8
$subtractMethod = Calculator::subtract(...);
echo $subtractMethod(10, 4); // 6
// ส่งเป็น callback
$numbers = [1, 2, 3, 4, 5];
$results = array_map($calc->add(...), $numbers, $numbers);
// [2, 4, 6, 8, 10]

<?php
// Factorial
function factorial(int $n): int {
if ($n <= 1) {
return 1; // Base case
}
return $n * factorial($n - 1); // Recursive case
}
echo factorial(5); // 120 (5 * 4 * 3 * 2 * 1)
// Fibonacci with memoization
function fibonacci(int $n, array &$memo = []): int {
if ($n <= 1) return $n;
if (!isset($memo[$n])) {
$memo[$n] = fibonacci($n - 1, $memo) + fibonacci($n - 2, $memo);
}
return $memo[$n];
}
echo fibonacci(10); // 55
// Flatten nested array
function flatten(array $array): array {
$result = [];
foreach ($array as $item) {
if (is_array($item)) {
$result = [...$result, ...flatten($item)];
} else {
$result[] = $item;
}
}
return $result;
}
echo json_encode(flatten([1, [2, 3], [[4, 5], 6]]));
// [1,2,3,4,5,6]

Functions ที่รับหรือ return functions อื่น:

<?php
// Function ที่รับ function เป็น parameter
function applyTwice(callable $func, $value) {
return $func($func($value));
}
$double = fn($n) => $n * 2;
echo applyTwice($double, 5); // 20 (5 * 2 * 2)
// Function ที่ return function
function multiplier(int $factor): callable {
return fn($n) => $n * $factor;
}
$triple = multiplier(3);
$quadruple = multiplier(4);
echo $triple(10); // 30
echo $quadruple(10); // 40
// Curry function
function curry(callable $func): callable {
$reflection = new ReflectionFunction($func);
$numParams = $reflection->getNumberOfParameters();
$curried = function(...$args) use ($func, $numParams, &$curried) {
if (count($args) >= $numParams) {
return $func(...$args);
}
return function(...$more) use ($args, $curried) {
return $curried(...$args, ...$more);
};
};
return $curried;
}
$add = curry(fn($a, $b, $c) => $a + $b + $c);
echo $add(1)(2)(3); // 6
echo $add(1, 2)(3); // 6
echo $add(1, 2, 3); // 6

PHP มี functions ในตัวมากมาย:

<?php
// String functions
strlen("hello"); // 5
strtoupper("hello"); // "HELLO"
substr("hello", 0, 3); // "hel"
str_replace("l", "L", "hello"); // "heLLo"
// Array functions
count([1, 2, 3]); // 3
array_sum([1, 2, 3]); // 6
array_map(fn($n) => $n * 2, [1, 2, 3]); // [2, 4, 6]
array_filter([1, 2, 3], fn($n) => $n > 1); // [2, 3]
// Math functions
abs(-5); // 5
ceil(4.3); // 5
floor(4.9); // 4
round(4.5); // 5
max(1, 2, 3); // 3
min(1, 2, 3); // 1
pow(2, 3); // 8
sqrt(16); // 4
// Date/Time
date("Y-m-d"); // "2024-01-15"
time(); // 1705312800 (timestamp)
strtotime("+1 week"); // timestamp ของสัปดาห์หน้า
// Type functions
gettype($var); // "string", "integer", etc.
is_string($var); // true/false
is_array($var); // true/false
isset($var); // true/false
empty($var); // true/false

แบบฝึกหัดที่ 1: Compose Functions

Section titled “แบบฝึกหัดที่ 1: Compose Functions”
<?php
function compose(callable ...$funcs): callable {
return function($value) use ($funcs) {
return array_reduce(
array_reverse($funcs),
fn($acc, $func) => $func($acc),
$value
);
};
}
// ใช้งาน
$double = fn($n) => $n * 2;
$addOne = fn($n) => $n + 1;
$square = fn($n) => $n ** 2;
$composed = compose($double, $addOne, $square);
echo $composed(3); // ((3^2) + 1) * 2 = 20

แบบฝึกหัดที่ 2: Memoize Function

Section titled “แบบฝึกหัดที่ 2: Memoize Function”
<?php
function memoize(callable $func): callable {
$cache = [];
return function(...$args) use ($func, &$cache) {
$key = serialize($args);
if (!isset($cache[$key])) {
$cache[$key] = $func(...$args);
}
return $cache[$key];
};
}
// ใช้งาน
$expensiveCalculation = memoize(function($n) {
echo "Calculating $n...\n";
return $n * 2;
});
echo $expensiveCalculation(5); // "Calculating 5..." → 10
echo $expensiveCalculation(5); // 10 (from cache, no "Calculating")
echo $expensiveCalculation(10); // "Calculating 10..." → 20

แบบฝึกหัดที่ 3: Pipe Function

Section titled “แบบฝึกหัดที่ 3: Pipe Function”
<?php
function pipe(mixed $value, callable ...$funcs): mixed {
return array_reduce(
$funcs,
fn($acc, $func) => $func($acc),
$value
);
}
// ใช้งาน
$result = pipe(
" Hello World ",
fn($s) => trim($s),
fn($s) => strtolower($s),
fn($s) => str_replace(" ", "-", $s)
);
echo $result; // "hello-world"

ในบทนี้เราได้เรียนรู้:

  • การสร้าง functions และ naming conventions
  • Parameters: required, default, nullable, variadic
  • Named arguments (PHP 8.0+)
  • Return types และ strict types
  • Variable scope: local, global, static
  • Anonymous functions และ closures
  • Arrow functions (PHP 7.4+)
  • First-class callables (PHP 8.1+)
  • Recursion และ higher-order functions

ในบทถัดไปเราจะเรียนรู้เกี่ยวกับ Arrays ใน PHP อย่างละเอียด

เข้าสู่ระบบเพื่อดูเนื้อหาเต็ม

ยืนยันตัวตนด้วยบัญชี Google เพื่อปลดล็อกบทความทั้งหมด