23/07/2019, 12:34

A curated collection of useful PHP

Hiện nay ngôn ngữ PHP có rất nhiều framework điển hình như Laravel, CakePHP, CodeIgniter, ... Ngoài các hàm mà php đã hỗ trợ thì các framework cũng đã hộ trợ rất nhiều các hàm để người lập trình dễ dàng thao tác với array, string, math. Tuy nhiên để hiểu chi tiết và các hàm được xây dựng và hoạt ...

Hiện nay ngôn ngữ PHP có rất nhiều framework điển hình như Laravel, CakePHP, CodeIgniter, ... Ngoài các hàm mà php đã hỗ trợ thì các framework cũng đã hộ trợ rất nhiều các hàm để người lập trình dễ dàng thao tác với array, string, math. Tuy nhiên để hiểu chi tiết và các hàm được xây dựng và hoạt động như nào thì không phải người lập trình nào cũng nắm được. Bài viết này sẽ giới thiệu cho chúng ta cách sử dụng cũng như cách viết của một số hàm hữu dụng.

  • all trả về là true nếu kết quả trả về là tất các các giá trị trong mảng và là false nếu ngược lại
function all($items, $func)
{
    return count(array_filter($items, $func)) === count($items);
}

ví dụ

all([2, 3, 4, 5], function ($item) {
    return $item > 1;
}); // true
  • any trả về là true nếu kết quả trả về ít nhất một phần tử trong mảng và là false nếu ngược lại
function any($items, $func)
{
    return count(array_filter($items, $func)) > 0;
}
any([1, 2, 3, 4], function ($item) {
    return $item < 2;
}); // true
  • deepFlatten Làm phẳng một mảng nhiều chiều thành mảng một chiều.
function deepFlatten($items)
{
    $result = [];
    foreach ($items as $item) {
        if (!is_array($item)) {
            $result[] = $item;
        } else {
            $result = array_merge($result, deepFlatten($item));
        }
    }

    return $result;
}

ví dụ

deepFlatten([1, [2], [[3], 4], 5]); // [1, 2, 3, 4, 5]
  • drop trả về một mảng với n phần tử được loại bỏ từ bên trái
function drop($items, $n = 1)
{
    return array_slice($items, $n);
}

ví dụ

drop([1, 2, 3]); // nếu khồng truyền vào tham số thì mặc định một phần từ bên trái bị loại bỏ khi này phần từ đâu tiên bên trái sẽ bị loại bỏ kết quả trả về còn magnr chưa 2 phần tử [2,3]
drop([1, 2, 3], 2); // [3]
  • findLast trả về phần tử cuối cùng thông qua điều kiện đã cho.
function findLast($items, $func)
{
    $filteredItems = array_filter($items, $func);

    return array_pop($filteredItems);
}

ví dụ

findLast([1, 2, 3, 4], function ($n) {
    return ($n % 2) === 1;
});
// 3

thông qua điều kiện có hai phân từ thỏa mãn [1, 3] và ta lấy phần tử cuối cùng là 3

  • findLastIndex trả về chỉ mục của phần tử cuối cùng thông qua điều kiện đã cho
function findLastIndex($items, $func)
{
    $keys = array_keys(array_filter($items, $func));

    return array_pop($keys);
}

ví dụ

findLastIndex([1, 2, 3, 4], function ($n) {
    return ($n % 2) === 1;
});
// 2
  • groupBy Nhóm các phần tử của mảng dựa trên hàm cho sẵn
function groupBy($items, $func)
{
    $group = [];
    foreach ($items as $item) {
        if ((!is_string($func) && is_callable($func)) || function_exists($func)) {
            $key = call_user_func($func, $item);
            $group[$key][] = $item;
        } elseif (is_object($item)) {
            $group[$item->{$func}][] = $item;
        } elseif (isset($item[$func])) {
            $group[$item[$func]][] = $item;
        }
    }

    return $group;
}

ví dụ

groupBy(['one', 'two', 'three'], 'strlen'); // [3 => ['one', 'two'], 5 => ['three']]

như ví dụ ở trên ta dựa vào hàm strlen để nhóm các phần tử có cùng số kí tự vào một nhóm với key là số kí tự.

  • hasDuplicates kiểm tra danh sách các phần tử trong mảng nếu có ít nhất hai giá trị phần tử trùng lặp thì trả về true còn các giá trị của mảng là duy nhất thì trả về false
function hasDuplicates($items)
{
    return count($items) > count(array_unique($items));
}

ví dụ

hasDuplicates([1, 2, 3, 4, 5, 5]); // true
hasDuplicates([1, 2, 3, 4, 5]); // false
  • head trả về giá trị phần tử đầu tiên của mảng
function head($items)
{
    return reset($items);
}

ví dụ

head([1, 2, 3]); // 1
  • last trả về giá trị phần tử cuối cùng của mảng
function last($items)
{
    return end($items);
}

ví dụ

last([1, 2, 3]); // 3
  • pluck lấy tất cả giá trị có chung key đã cho sẵn
function pluck($items, $key)
{
    return array_map( function($item) use ($key) {
        return is_object($item) ? $item->$key : $item[$key];
    }, $items);
}

ví dụ

pluck([
    ['product_id' => 'prod-100', 'name' => 'Desk'],
    ['product_id' => 'prod-200', 'name' => 'Chair'],
], 'name');
// ['Desk', 'Chair']

ở ví dụ trên hàm pluck trả về một mảng có chung key là 'name' mà ta truyền vào.

  • pull để lọc ra các giá trị được truyền vào.
function pull(&$items, ...$params)
{
    $items = array_values(array_diff($items, $params));
    
    return $items;
}

ví dụ

$items = ['a', 'b', 'c', 'a', 'b', 'c'];
pull($items, 'a', 'c'); // $items will be ['b', 'b']

ở ví dụ trên khi truyền vào hàm pull 2 giá trị 'a', 'c' thì hai giá trị này đã bị loại bỏ ra khỏi mảng.

  • reject loại bỏ các phần tử không thỏa mãn điều kiện cho trước
function reject($items, $func)
{
    return array_values(array_diff($items, array_filter($items, $func)));
}

ví dụ

reject(['Apple', 'Pear', 'Kiwi', 'Banana'], function ($item) {
    return strlen($item) > 4;
}); // ['Pear', 'Kiwi']
  • remove loại bỏ các phần tử trong mảng khi hàm trả về là false
function remove($items, $func)
{
    $filtered = array_filter($items, $func);

    return array_diff_key($items, $filtered);
}

ví dụ

remove([1, 2, 3, 4], function ($n) {
    return ($n % 2) === 0;
});
// [0 => 1, 2 => 3]
  • tail lấy tất cả các phần từ của mảng trừ phần tử đầu tiên
function tail($items)
{
    return count($items) > 1 ? array_slice($items, 1) : $items;
}

ví dụ

tail([1, 2, 3]); // [2, 3]
  • take lấy ra một mảng gồm n phần tử đầu tiên
function take($items, $n = 1)
{
    return array_slice($items, 0, $n);
}

ví dụ

take([1, 2, 3], 5); // [1, 2, 3]
take([1, 2, 3, 4, 5], 2); // [1, 2]
  • without loại bỏ các phần tử mà giá trị của nó trùng với giá trị của các phần từ truyền vào
function without($items, ...$params)
{
    return array_values(array_diff($items, $params));
}

ví dụ

without([2, 1, 2, 3], 1, 2); // [3]
  • orderBy sắp sếp tăng dần hoặc giảm dần các giá trị của mảng theo key truyền vào
function orderBy($items, $attr, $order)
{
    $sortedItems = [];
    foreach ($items as $item) {
        $key = is_object($item) ? $item->{$attr} : $item[$attr];
        $sortedItems[$key] = $item;
    }
    if ($order === 'desc') {
        krsort($sortedItems);
    } else {
        ksort($sortedItems);
    }

    return array_values($sortedItems);
}

ví dụ

orderBy(
    [
        ['id' => 2, 'name' => 'Joy'],
        ['id' => 3, 'name' => 'Khaja'],
        ['id' => 1, 'name' => 'Raja']
    ],
    'id',
    'desc'
); // [['id' => 3, 'name' => 'Khaja'], ['id' => 2, 'name' => 'Joy'], ['id' => 1, 'name' => 'Raja']]
  • average trả về giá trị trung bình của các giá trị truyền vào
function average(...$items)
{
    $count = count($items);
    
    return $count === 0 ? 0 : array_sum($items) / $count;
}

ví dụ

average(1, 2, 3); // 2
  • factorial dùng đệ quy để tính giai thừa
function factorial($n)
{
    if ($n <= 1) {
        return 1;
    }

    return $n * factorial($n - 1);
}

ví dụ

factorial(6); // 720
  • gcd tính ước số chung lớn nhất của hai hay nhiều số
function gcd(...$numbers)
{
    if (count($numbers) > 2) {
        return array_reduce($numbers, 'gcd');
    }

    $r = $numbers[0] % $numbers[1];
    return $r === 0 ? abs($numbers[1]) : gcd($numbers[1], $r);
}

ví dụ

gcd(8, 36); // 4
gcd(12, 8, 32); // 4
  • median tính trung bị của một mảng

function median($numbers)
{
    sort($numbers);
    $totalNumbers = count($numbers);
    $mid = floor($totalNumbers / 2);

    return ($totalNumbers % 2) === 0 ? ($numbers[$mid - 1] + $numbers[$mid]) / 2 : $numbers[$mid];
}

ví dụ

median([1, 3, 3, 6, 7, 8, 9]); // 6
median([1, 2, 3, 6, 7, 9]); // 4.5
  • endsWith kiểm tra chuỗi kết thúc có phải là chuỗi truyền vào hay không
function endsWith($haystack, $needle)
{
    return strrpos($haystack, $needle) === (strlen($haystack) - strlen($needle));
}

ví dụ

endsWith('Hi, this is me', 'me'); // true
  • firstStringBetween trả về chuỗi đầu tiên giữa tham số bắt đầu và tham số kết thúc
function firstStringBetween($haystack, $start, $end)
{
    return trim(strstr(strstr($haystack, $start), $end, true), $start . $end);
}

ví dụ

firstStringBetween('This is a [custom] string', '[', ']'); // custom

tham số bắt đầu là '[' tham số kết thúc là ']'

  • isAnagram so sánh 2 chuỗi và trả về là true nếu 2 chuối đố là đảo người của nhau là false nếu ngược lại
function isAnagram($string1, $string2)
{
    return count_chars($string1, 1) === 
                                          
0