Kotchasan Framework Documentation

Kotchasan Framework Documentation

Kotchasan\ArrayTool

TH 03 Feb 2026 11:45

Kotchasan\ArrayTool

ภาพรวม

ArrayTool เป็น utility class ที่ให้เครื่องมือสำหรับการจัดการ arrays และ objects อย่างมีประสิทธิภาพ คลาสนี้ให้ฟังก์ชันที่ไม่มีใน native PHP หรือให้ความสะดวกมากกว่าฟังก์ชันมาตรฐาน

ใช้เมื่อไหร่:

  • ต้องการดึงข้อมูลจาก column เฉพาะใน array of arrays/objects
  • ต้องการค้นหาหรือกรองข้อมูลตามเงื่อนไขที่ซับซ้อน
  • ต้องการแทรกข้อมูลในตำแหน่งเฉพาะของ array
  • ต้องการจัดการ arrays และ objects ในรูปแบบเดียวกัน

จุดเด่น:

  • ทำงานได้กับทั้ง arrays และ objects
  • มี helper functions ที่เพิ่มความสะดวกเหนือ native PHP
  • รองรับการค้นหาและกรองข้อมูลแบบ case-insensitive
  • สามารถจัดการ nested arrays/objects ได้

[!NOTE]
เอกสารนี้อ้างอิง API ของ ArrayTool สำหรับ PHP 7.4+. คลาสนี้เน้นไปที่ helper ที่ให้คุณค่ามากกว่าฟังก์ชัน native ของ PHP

API Reference

columns()

ดึงค่าจาก column เฉพาะจาก array หรือ object (คล้าย array_column() แต่ทำงานได้กับทั้ง arrays และ objects)

Signature:

public static function columns(iterable $source, string $column_key, ?string $index_key = null): array

Parameters:

  • $source (iterable) - Array, object, หรือ array of objects ที่จะดึงข้อมูล
  • $column_key (string) - ชื่อ column ที่ต้องการดึง
  • $index_key (string|null) - Column ที่จะใช้เป็น index (null = ใช้ numeric index)

Returns: Array ของค่าที่ดึงมา

ตัวอย่างการใช้งาน:

use Kotchasan\ArrayTool;

$users = [
    ['id' => 1, 'name' => 'Alice', 'email' => 'alice@example.com'],
    ['id' => 2, 'name' => 'Bob', 'email' => 'bob@example.com'],
    ['id' => 3, 'name' => 'Charlie', 'email' => 'charlie@example.com']
];

// ดึงชื่อทั้งหมด (numeric index)
$names = ArrayTool::columns($users, 'name');
// Result: ['Alice', 'Bob', 'Charlie']

// ดึง email โดยใช้ id เป็น index
$emailsById = ArrayTool::columns($users, 'email', 'id');
// Result: [1 => 'alice@example.com', 2 => 'bob@example.com', 3 => 'charlie@example.com']

ทำงานกับ objects:

$users = [
    (object)['id' => 1, 'name' => 'Alice'],
    (object)['id' => 2, 'name' => 'Bob']
];

$names = ArrayTool::columns($users, 'name', 'id');
// Result: [1 => 'Alice', 2 => 'Bob']

extract()

แยก keys และ values จาก nested array แบบ recursive

Signature:

public static function extract(array $array, array &$keys, array &$values): void

Parameters:

  • $array (array) - Array ต้นฉบับ (สามารถเป็น nested ได้)
  • $keys (array) - Reference array สำหรับเก็บ keys ที่ดึงออกมา
  • $values (array) - Reference array สำหรับเก็บ values ที่ดึงออกมา

Returns: void (แก้ไข $keys และ $values ผ่าน reference)

ตัวอย่างการใช้งาน:

$data = [
    'name' => 'John',
    'address' => [
        'city' => 'Bangkok',
        'country' => 'Thailand'
    ],
    'age' => 30
];

$keys = [];
$values = [];
ArrayTool::extract($data, $keys, $values);

// $keys = ['name', 'city', 'country', 'age']
// $values = ['John', 'Bangkok', 'Thailand', 30]

filter()

กรอง array elements ที่มี search string (case-insensitive)

Signature:

public static function filter(array $array, string $search): array

Parameters:

  • $array (array) - Array ที่จะกรอง
  • $search (string) - คำค้นหา

Returns: Array ที่ผ่านการกรอง (คงค่า original keys)

ตัวอย่างการใช้งาน:

$items = [
    'apple',
    'banana',
    'orange',
    'grape',
    'pineapple'
];

$filtered = ArrayTool::filter($items, 'app');
// Result: [0 => 'apple', 4 => 'pineapple'] (contains 'app')

// กรองด้วย empty string จะคืนค่า array เดิม
$all = ArrayTool::filter($items, '');
// Result: ['apple', 'banana', 'orange', 'grape', 'pineapple']

ใช้กับ nested arrays:

$products = [
    ['name' => 'Laptop', 'brand' => 'Dell'],
    ['name' => 'Mouse', 'brand' => 'Logitech'],
    ['name' => 'Keyboard', 'brand' => 'Dell']
];

// ค้นหาสินค้า Dell
$dellProducts = ArrayTool::filter($products, 'Dell');
// Result: [0 => ['name' => 'Laptop', 'brand' => 'Dell'],
//          2 => ['name' => 'Keyboard', 'brand' => 'Dell']]

getFirstKey()

ดึง key แรกของ array หรือ object

Signature:

public static function getFirstKey($source)

Parameters:

  • $source (array|object) - Array หรือ object

Returns: string|int|null - Key แรก หรือ null ถ้าไม่มี keys

ตัวอย่างการใช้งาน:

$array = ['name' => 'John', 'age' => 30, 'city' => 'Bangkok'];
$firstKey = ArrayTool::getFirstKey($array);
// Result: 'name'

$object = (object)['id' => 1, 'title' => 'Test'];
$firstKey = ArrayTool::getFirstKey($object);
// Result: 'id'

$empty = [];
$firstKey = ArrayTool::getFirstKey($empty);
// Result: null

[!NOTE]
สำหรับ arrays ใน PHP 7.3+, คุณสามารถใช้ array_key_first() แทนได้ Method นี้ให้ไว้เพื่อรองรับ objects

insertAfter()

แทรกข้อมูลเข้าไปใน array หลังจาก key ที่ระบุ

Signature:

public static function insertAfter(array $source, $find, $key, $value): array

Parameters:

  • $source (array) - Array ที่จะแทรกข้อมูล
  • $find (string|int) - Key ที่จะหา
  • $key (string|int) - Key สำหรับข้อมูลใหม่
  • $value (mixed) - ข้อมูลที่จะแทรก

Returns: Array ที่ถูกแก้ไข (ถ้าหา key ไม่เจอ จะแทรกที่ท้าย array)

ตัวอย่างการใช้งาน:

$menu = [
    'home' => 'หน้าแรก',
    'about' => 'เกี่ยวกับเรา',
    'contact' => 'ติดต่อ'
];

// แทรกหลัง 'home'
$menu = ArrayTool::insertAfter($menu, 'home', 'services', 'บริการ');
// Result: [
//     'home' => 'หน้าแรก',
//     'services' => 'บริการ',
//     'about' => 'เกี่ยวกับเรา',
//     'contact' => 'ติดต่อ'
// ]

// ถ้าหา key ไม่เจอ จะแทรกที่ท้าย
$menu = ArrayTool::insertAfter($menu, 'notfound', 'blog', 'บล็อก');
// 'blog' จะถูกเพิ่มที่ท้าย array

insertBefore()

แทรกข้อมูลเข้าไปใน array ก่อน key ที่ระบุ

Signature:

public static function insertBefore(array $source, $find, $key, $value): array

Parameters:

  • $source (array) - Array ที่จะแทรกข้อมูล
  • $find (string|int) - Key ที่จะหา
  • $key (string|int) - Key สำหรับข้อมูลใหม่
  • $value (mixed) - ข้อมูลที่จะแทรก

Returns: Array ที่ถูกแก้ไข (ถ้าหา key ไม่เจอ จะแทรกที่ท้าย array)

ตัวอย่างการใช้งาน:

$menu = [
    'home' => 'หน้าแรก',
    'contact' => 'ติดต่อ'
];

// แทรกก่อน 'contact'
$menu = ArrayTool::insertBefore($menu, 'contact', 'about', 'เกี่ยวกับเรา');
// Result: [
//     'home' => 'หน้าแรก',
//     'about' => 'เกี่ยวกับเรา',
//     'contact' => 'ติดต่อ'
// ]

replace()

แทนที่/เพิ่มค่าใน array หรือ object (ทำงานกับทั้ง arrays และ objects)

Signature:

public static function replace($source, $replace)

Parameters:

  • $source (array|object) - Array หรือ object ต้นฉบับ
  • $replace (array|object) - ค่าที่จะแทนที่/เพิ่ม

Returns: array|object - Source ที่ถูกแก้ไข

ตัวอย่างการใช้งาน:

// ใช้กับ array
$data = ['a' => 1, 'b' => 2, 'c' => 3];
$replacements = ['b' => 5, 'd' => 4];

$result = ArrayTool::replace($data, $replacements);
// Result: ['a' => 1, 'b' => 5, 'c' => 3, 'd' => 4]

// ใช้กับ object
$config = (object)['host' => 'localhost', 'port' => 3306];
$updates = ['port' => 3307, 'database' => 'test'];

$config = ArrayTool::replace($config, $updates);
// Result: object with host='localhost', port=3307, database='test'

ค้นหา items ใน array of arrays/objects ที่มี key-value คู่ที่ตรงกัน

Signature:

public static function search(array $array, string $key, $search): array

Parameters:

  • $array (array) - Array of arrays หรือ objects ที่จะค้นหา
  • $key (string) - Key/property ที่จะเปรียบเทียบ
  • $search (mixed) - ค่าที่จะค้นหา (ใช้ strict comparison)

Returns: Array ของ items ที่ตรงกัน (คงค่า original keys)

ตัวอย่างการใช้งาน:

$users = [
    ['id' => 1, 'name' => 'Alice', 'status' => 'active'],
    ['id' => 2, 'name' => 'Bob', 'status' => 'inactive'],
    ['id' => 3, 'name' => 'Charlie', 'status' => 'active'],
    ['id' => 4, 'name' => 'Diana', 'status' => 'pending']
];

// ค้นหาผู้ใช้ที่ active
$activeUsers = ArrayTool::search($users, 'status', 'active');
// Result: [
//     0 => ['id' => 1, 'name' => 'Alice', 'status' => 'active'],
//     2 => ['id' => 3, 'name' => 'Charlie', 'status' => 'active']
// ]

// ค้นหาด้วย boolean
$items = [
    ['name' => 'Item 1', 'featured' => true],
    ['name' => 'Item 2', 'featured' => false],
    ['name' => 'Item 3', 'featured' => true]
];

$featured = ArrayTool::search($items, 'featured', true);
// Result: [0 => ..., 2 => ...]

ทำงานกับ objects:

$users = [
    (object)['id' => 1, 'role' => 'admin'],
    (object)['id' => 2, 'role' => 'user']
];

$admins = ArrayTool::search($users, 'role', 'admin');
// Result: [0 => object(['id' => 1, 'role' => 'admin'])]

shift()

ลบ elements จาก array ก่อนหน้า key ที่ระบุ (เก็บเฉพาะข้อมูลตั้งแต่ key ที่ระบุเป็นต้นไป)

Signature:

public static function shift(array $source, $key): array

Parameters:

  • $source (array) - Array ต้นฉบับ
  • $key (string|int) - Key ที่จะเริ่มเก็บข้อมูล

Returns: Array ของ elements จาก key ที่ระบุเป็นต้นไป

ตัวอย่างการใช้งาน:

$data = [
    'step1' => 'เริ่มต้น',
    'step2' => 'ดำเนินการ',
    'step3' => 'เสร็จสิ้น',
    'step4' => 'ปิด'
];

$remaining = ArrayTool::shift($data, 'step2');
// Result: [
//     'step2' => 'ดำเนินการ',
//     'step3' => 'เสร็จสิ้น',
//     'step4' => 'ปิด'
// ]

// ใช้กับ numeric array
$numbers = [10, 20, 30, 40, 50];
$fromIndex2 = ArrayTool::shift($numbers, 2);
// Result: [2 => 30, 3 => 40, 4 => 50]

sort()

เรียงลำดับ array of associative arrays/objects ตาม key ที่ระบุ

Signature:

public static function sort(array $array, string $sort_key = 'id', bool $descending = false): array

Parameters:

  • $array (array) - Array ที่จะเรียงลำดับ
  • $sort_key (string) - Key ที่จะใช้ในการเรียงลำดับ (default: 'id')
  • $descending (bool) - เรียงจากมากไปน้อย (default: false = ascending)

Returns: Array ที่เรียงลำดับแล้ว (re-indexed numerically)

ตัวอย่างการใช้งาน:

$products = [
    ['id' => 3, 'name' => 'Product C', 'price' => 100],
    ['id' => 1, 'name' => 'Product A', 'price' => 300],
    ['id' => 2, 'name' => 'Product B', 'price' => 200]
];

// เรียงตาม id (ascending)
$sortedById = ArrayTool::sort($products, 'id');
// Result: [
//     0 => ['id' => 1, 'name' => 'Product A', 'price' => 300],
//     1 => ['id' => 2, 'name' => 'Product B', 'price' => 200],
//     2 => ['id' => 3, 'name' => 'Product C', 'price' => 100]
// ]

// เรียงตาม price (descending)
$sortedByPrice = ArrayTool::sort($products, 'price', true);
// Result: [
//     0 => ['id' => 1, 'name' => 'Product A', 'price' => 300],
//     1 => ['id' => 2, 'name' => 'Product B', 'price' => 200],
//     2 => ['id' => 3, 'name' => 'Product C', 'price' => 100]
// ]

// เรียงตาม name (alphabetically)
$sortedByName = ArrayTool::sort($products, 'name');
// Result: เรียงตามตัวอักษร (case-insensitive)

[!NOTE]
การเรียงลำดับใช้ case-insensitive comparison และ array ที่ return จะถูก re-index เป็นตัวเลข (0, 1, 2...)

toString()

แปลง nested array/object เป็น string โดยรวม values แบบ recursive

Signature:

public static function toString(string $glue, $source): string

Parameters:

  • $glue (string) - ตัวคั่นระหว่าง values
  • $source (mixed) - Array, object, หรือ scalar value

Returns: string - String ที่รวมกัน

ตัวอย่างการใช้งาน:

// Simple array
$data = ['apple', 'banana', 'orange'];
$result = ArrayTool::toString(', ', $data);
// Result: "apple, banana, orange"

// Nested array
$nested = [
    'user' => [
        'name' => 'John',
        'details' => ['age' => 30, 'city' => 'Bangkok']
    ]
];

$result = ArrayTool::toString(' | ', $nested);
// Result: "John | 30 | Bangkok"

// ใช้กับ scalar value
$value = ArrayTool::toString(',', 'test');
// Result: "test"

unserialize()

Unserialize string และอัปเดต source array ด้วยข้อมูล unserialized (รองรับทั้ง JSON และ PHP serialize)

Signature:

public static function unserialize($str, $source = [], $replace = true)

Parameters:

  • $str (string) - String ที่ serialized
  • $source (array) - Array ที่จะอัปเดต (optional, default: [])
  • $replace (bool) - แทนที่ค่าเดิมหรือไม่ (optional, default: true)

Returns: array - Source array ที่อัปเดตแล้ว

ตัวอย่างการใช้งาน:

// JSON string
$json = '{"name":"John","age":30,"city":"Bangkok"}';
$data = ArrayTool::unserialize($json);
// Result: ['name' => 'John', 'age' => 30, 'city' => 'Bangkok']

// PHP serialized string
$serialized = serialize(['id' => 1, 'status' => 'active']);
$data = ArrayTool::unserialize($serialized);
// Result: ['id' => 1, 'status' => 'active']

// Merge กับ existing array
$existing = ['host' => 'localhost', 'port' => 3306];
$updates = '{"port":3307,"database":"mydb"}';

$config = ArrayTool::unserialize($updates, $existing);
// Result: ['host' => 'localhost', 'port' => 3307, 'database' => 'mydb']

// ไม่แทนที่ค่าเดิม (replace = false)
$existing = ['name' => 'Alice', 'age' => 25];
$updates = '{"name":"Bob","city":"Bangkok"}';

$data = ArrayTool::unserialize($updates, $existing, false);
// Result: ['name' => 'Alice', 'age' => 25, 'city' => 'Bangkok']
// (name ไม่ถูกแทนที่เพราะมีอยู่แล้ว)

[!NOTE]
ฟังก์ชันนี้จะพยายาม decode เป็น JSON ก่อน ถ้าไม่สำเร็จจะใช้ unserialize() แทน

inArrayAny()

ตรวจสอบว่ามีค่าใดๆ จาก needle array อยู่ใน haystack array หรือไม่

Signature:

public static function inArrayAny(array $needles, array $haystack, bool $strict = false): bool

Parameters:

  • $needles (array) - Array ของค่าที่ต้องการค้นหา
  • $haystack (array) - Array เป้าหมาย
  • $strict (bool) - ใช้ strict type comparison หรือไม่ (default: false)

Returns: bool - true ถ้ามีค่าใดๆ เจอ

ตัวอย่างการใช้งาน:

$permissions = ['read', 'write', 'delete'];
$userPermissions = ['read', 'execute'];

// ตรวจสอบว่าผู้ใช้มี permission ใดๆ ที่ต้องการหรือไม่
$hasAny = ArrayTool::inArrayAny($permissions, $userPermissions);
// Result: true (มี 'read')

$adminPermissions = ['create', 'delete'];
$hasAny = ArrayTool::inArrayAny($adminPermissions, $userPermissions);
// Result: false (ไม่มีเลย)

// ใช้ strict comparison
$numbers = ['1', '2', '3'];
$check = [1, 4];

$found = ArrayTool::inArrayAny($check, $numbers, false);
// Result: true ('1' == 1 เป็น true)

$found = ArrayTool::inArrayAny($check, $numbers, true);
// Result: false ('1' === 1 เป็น false)

[!NOTE]
ต่างจาก native in_array() ที่รับค่าเดียว, ฟังก์ชันนี้รับ array ของค่า และคืน true ถ้าพบค่าใดๆ

getNextKey()

ดึง key ของ element ถัดไปหลังจาก key ที่ระบุใน array

Signature:

public static function getNextKey(array $array, $key)

Parameters:

  • $array (array) - Array ต้นฉบับ
  • $key (string|int) - Key ที่ต้องการหา key ถัดไป

Returns: string|int|null - Key ถัดไป, หรือ null ถ้าไม่เจอหรืออยู่ที่ท้าย array

ตัวอย่างการใช้งาน:

$menu = [
    'home' => 'หน้าแรก',
    'about' => 'เกี่ยวกับเรา',
    'services' => 'บริการ',
    'contact' => 'ติดต่อ'
];

$nextKey = ArrayTool::getNextKey($menu, 'about');
// Result: 'services'

$nextKey = ArrayTool::getNextKey($menu, 'contact');
// Result: null (อยู่ที่ท้าย array)

$nextKey = ArrayTool::getNextKey($menu, 'notfound');
// Result: null (ไม่มี key นี้)

// ใช้กับ numeric array
$numbers = [10, 20, 30, 40];
$nextKey = ArrayTool::getNextKey($numbers, 1);
// Result: 2

ตัวอย่างการใช้งานจริง

1. จัดการข้อมูลผู้ใช้

use Kotchasan\ArrayTool;

class UserManager
{
    private $users = [
        ['id' => 1, 'name' => 'Alice', 'role' => 'admin', 'active' => true],
        ['id' => 2, 'name' => 'Bob', 'role' => 'user', 'active' => true],
        ['id' => 3, 'name' => 'Charlie', 'role' => 'user', 'active' => false],
        ['id' => 4, 'name' => 'Diana', 'role' => 'moderator', 'active' => true]
    ];

    /**
     * ดึงผู้ใช้ที่เปิดใช้งาน
     */
    public function getActiveUsers()
    {
        return ArrayTool::search($this->users, 'active', true);
    }

    /**
     * ดึงผู้ดูแลระบบทั้งหมด
     */
    public function getAdmins()
    {
        return ArrayTool::search($this->users, 'role', 'admin');
    }

    /**
     * ดึงรายชื่อผู้ใช้ (indexed by ID)
     */
    public function getUserNamesById()
    {
        return ArrayTool::columns($this->users, 'name', 'id');
        // Result: [1 => 'Alice', 2 => 'Bob', 3 => 'Charlie', 4 => 'Diana']
    }

    /**
     * ค้นหาผู้ใช้ตามคำค้นหา
     */
    public function searchUsers($term)
    {
        return ArrayTool::filter($this->users, $term);
    }

    /**
     * เรียงผู้ใช้ตามชื่อ
     */
    public function sortByName($descending = false)
    {
        return ArrayTool::sort($this->users, 'name', $descending);
    }
}

// การใช้งาน
$manager = new UserManager();

$active = $manager->getActiveUsers();
$admins = $manager->getAdmins();
$nameMap = $manager->getUserNamesById();
$searchResults = $manager->searchUsers('ali'); // ค้นหา case-insensitive

2. สร้างและจัดการเมนู

class MenuBuilder
{
    private $menu = [];

    public function __construct()
    {
        $this->menu = [
            'home' => ['title' => 'หน้าแรก', 'url' => '/', 'icon' => 'home'],
            'contact' => ['title' => 'ติดต่อ', 'url' => '/contact', 'icon' => 'mail']
        ];
    }

    /**
     * เพิ่มเมนูหลัง home
     */
    public function addMenuAfterHome($key, $title, $url, $icon)
    {
        $item = ['title' => $title, 'url' => $url, 'icon' => $icon];
        $this->menu = ArrayTool::insertAfter($this->menu, 'home', $key, $item);
        return $this;
    }

    /**
     * เพิ่มเมนูก่อน contact
     */
    public function addMenuBeforeContact($key, $title, $url, $icon)
    {
        $item = ['title' => $title, 'url' => $url, 'icon' => $icon];
        $this->menu = ArrayTool::insertBefore($this->menu, 'contact', $key, $item);
        return $this;
    }

    /**
     * อัปเดตเมนู
     */
    public function updateMenu($updates)
    {
        foreach ($updates as $key => $data) {
            if (isset($this->menu[$key])) {
                $this->menu[$key] = ArrayTool::replace($this->menu[$key], $data);
            }
        }
        return $this;
    }

    /**
     * ดึงชื่อเมนูทั้งหมด
     */
    public function getMenuTitles()
    {
        return ArrayTool::columns($this->menu, 'title');
    }

    public function getMenu()
    {
        return $this->menu;
    }
}

// การใช้งาน
$builder = new MenuBuilder();

$builder
    ->addMenuAfterHome('about', 'เกี่ยวกับเรา', '/about', 'info')
    ->addMenuBeforeContact('services', 'บริการ', '/services', 'briefcase')
    ->updateMenu([
        'home' => ['icon' => 'house'] // เปลี่ยน icon
    ]);

$menu = $builder->getMenu();
// Result: [
//     'home' => ['title' => 'หน้าแรก', 'url' => '/', 'icon' => 'house'],
//     'about' => ['title' => 'เกี่ยวกับเรา', 'url' => '/about', 'icon' => 'info'],
//     'services' => ['title' => 'บริการ', 'url' => '/services', 'icon' => 'briefcase'],
//     'contact' => ['title' => 'ติดต่อ', 'url' => '/contact', 'icon' => 'mail']
// ]

3. ประมวลผลข้อมูล API

class ApiDataProcessor
{
    /**
     * ประมวลผล response จาก API
     */
    public function processUserResponse($apiResponse)
    {
        $users = $apiResponse['data']['users'] ?? [];

        // ดึงข้อมูลที่ต้องการ
        $emails = ArrayTool::columns($users, 'email');
        $userMap = ArrayTool::columns($users, 'name', 'id');

        // กรองผู้ใช้ที่ verified
        $verified = ArrayTool::search($users, 'verified', true);

        // เรียงตามวันที่สร้าง
        $sorted = ArrayTool::sort($verified, 'created_at', true);

        return [
            'emails' => $emails,
            'user_map' => $userMap,
            'verified_users' => $verified,
            'latest_users' => $sorted
        ];
    }

    /**
     * รวมข้อมูลจากหลาย sources
     */
    public function mergeUserData($users, $profiles)
    {
        foreach ($users as &$user) {
            $userId = $user['id'];
            $profileData = ArrayTool::search($profiles, 'user_id', $userId);

            if (!empty($profileData)) {
                $user = ArrayTool::replace($user, $profileData[0]);
            }
        }

        return $users;
    }

    /**
     * ทำความสะอาดข้อมูล (ลบ sensitive fields)
     */
    public function sanitize($data)
    {
        $sensitiveFields = ['password', 'token', 'secret_key'];

        foreach ($data as &$item) {
            $item = array_diff_key($item, array_flip($sensitiveFields));
        }

        return $data;
    }
}

4. จัดการ Permissions

class PermissionChecker
{
    /**
     * ตรวจสอบว่าผู้ใช้มี permission ที่ต้องการหรือไม่
     */
    public function hasAnyPermission($userPermissions, $requiredPermissions)
    {
        return ArrayTool::inArrayAny($requiredPermissions, $userPermissions);
    }

    /**
     * ตรวจสอบว่าผู้ใช้มี role ที่อนุญาต
     */
    public function hasRole($userRoles, $allowedRoles)
    {
        return ArrayTool::inArrayAny($allowedRoles, $userRoles);
    }
}

// การใช้งาน
$checker = new PermissionChecker();

$userPerms = ['post:read', 'post:create', 'comment:read'];
$requiredPerms = ['post:delete', 'post:update'];

$canEdit = $checker->hasAnyPermission($userPerms, $requiredPerms);
// Result: false (ไม่มี permission ที่ต้องการ)

$userRoles = ['editor', 'author'];
$adminRoles = ['admin', 'super-admin'];

$isAdmin = $checker->hasRole($userRoles, $adminRoles);
// Result: false

Best Practices

1. ตรวจสอบข้อมูลก่อนใช้งาน

// ✅ ดี
public function safeColumnExtraction($data, $column)
{
    if (!is_array($data) || empty($data)) {
        return [];
    }

    // ตรวจสอบว่า column มีอยู่
    $firstItem = reset($data);
    if (!isset($firstItem[$column])) {
        throw new InvalidArgumentException("Column '{$column}' not found");
    }

    return ArrayTool::columns($data, $column);
}

// ❌ ไม่ดี - ไม่ตรวจสอบข้อมูล
public function unsafeExtraction($data, $column)
{
    return ArrayTool::columns($data, $column); // อาจ error
}

2. ใช้ Native PHP Functions เมื่อเหมาะสม

// สำหรับการ access array อย่างปลอดภัย
// ✅ ใช้ null coalescing operator
$value = $config['key'] ?? 'default';

// สำหรับการลบ keys
// ✅ ใช้ native functions
$result = array_diff_key($array, array_flip(['key1', 'key2']));

// สำหรับการดึง first key (PHP 7.3+)
// ✅ ใช้ native function for arrays
$firstKey = array_key_first($array);

// แต่ถ้าต้องรองรับ objects ใช้ ArrayTool::getFirstKey()
$firstKey = ArrayTool::getFirstKey($object);

3. Performance สำหรับข้อมูลขนาดใหญ่

// สำหรับข้อมูลขนาดใหญ่ (> 1000 items)
// พิจารณาใช้ array_filter หรือ foreach แทน
public function efficientSearch($data, $key, $value)
{
    if (count($data) > 1000) {
        return array_filter($data, function($item) use ($key, $value) {
            return isset($item[$key]) && $item[$key] === $value;
        });
    }

    return ArrayTool::search($data, $key, $value);
}

4. Type Safety

// ✅ ระบุ types ชัดเจน
public function typeSafeReplace($source, array $replacements)
{
    if (!is_array($source) && !is_object($source)) {
        throw new InvalidArgumentException('Source must be array or object');
    }

    return ArrayTool::replace($source, $replacements);
}

ข้อควรระวัง

[!WARNING]
sort() ทำให้ array ถูก re-index
ฟังก์ชัน sort() จะคืนค่า array ที่ถูก re-index เป็นตัวเลข (0, 1, 2...) แทนที่จะคง original keys

// Original keys จะหายไป
$data = [
    'user1' => ['name' => 'Bob'],
    'user2' => ['name' => 'Alice']
];

$sorted = ArrayTool::sort($data, 'name');
// Result: [
//     0 => ['name' => 'Alice'],
//     1 => ['name' => 'Bob']
// ]
// ไม่ใช่ ['user2' => ..., 'user1' => ...]

[!WARNING]
search() ใช้ strict comparison
ฟังก์ชัน search() ใช้ === ในการเปรียบเทียบ ระวังเรื่อง type

$users = [['id' => 1], ['id' => '1']];

ArrayTool::search($users, 'id', 1);   // จะได้แค่ ['id' => 1]
ArrayTool::search($users, 'id', '1'); // จะได้แค่ ['id' => '1']

[!CAUTION]
Memory usage กับ nested arrays
การใช้ toString() กับ nested arrays ขนาดใหญ่อาจใช้ memory มาก

คลาสที่เกี่ยวข้อง

  • Collection - สำหรับจัดการ collections
  • Database - สำหรับ query results
  • Text - สำหรับจัดการ strings