- vừa được xem lúc

PHP thuần: Collection helper

0 0 34

Người đăng: Nguyễn Thế Mạnh

Theo Viblo Asia

Đối với những ai đã từng sử dụng framework laravel, thì sự thuận tiện của collection helper là không thể phủ nhận. Nó giúp chúng ta thao tác với dữ liệu một cách thuận tiện và trôi chảy hơn. Tuy nhiên, không phải lúc nào các dự án của chúng ta đều được phép sử dụng framework. Vì khi sử dụng framework, một khi có lỗi xảy ra thì chúng ta rất khó để control. Trong bài viết này, mình xin chia sẻ cách tạo một collection trong PHP thuần.

1. Khởi tạo collection

Đầu tiên, coletion phải có khả năng sử dụng trong vòng lặp giống như một array. Collection phải implements IteratorAggregate interface để tạo một Iterator bên ngoài.

<?php use ArrayIterator;
use IteratorAggregate; class Collection implements IteratorAggregate
{ /** * Khởi taọ thuộc tính để chứa các giá trị từ mảng. * * @var \ArrayIterator */ protected $items = []; /** * Khởi tạo items bằng cách tạo một instance của ArrayIterator. * * @param array $items * @return void */ public function __construct($items = []) { $this->items = new ArrayIterator($this->getArrayableItems($items)); } /** * Hàm này sẽ trả về một array cho việc khởi tạo thuộc tính items ở hàm __construct. * * @param mixed $items * @return array */ protected function getArrayableItems($items) { if (is_array($items)) { // Nếu là một array thì return $item luôn return $items; } elseif ($items instanceof Traversable) { // Nếu là một thể hiện của Traversable thì sử dụng hàm iterator_to_array để chuyển từ iterator về array return iterator_to_array($items); } return (array) $items; // nếu là loại khác, ép kiểu về dạng array } /** * Get an iterator for the items. * * @return \ArrayIterator */ public function getIterator() { return $this->items; }
}

Giải thích: Khi chúng ta sử dụng colection trong một vòng lặp, php sẽ kiểm tra xem tham số được sử dụng để lặp có phải là một đối tượng có thể lặp hay không. Việc implements IteratorAggregate interface giúp chúng ta tạo ra một đối tượng như vậy. Interface này yêu cầu chúng ta khởi tạo phương thức getIterator, giá trị trả về là một thể hiện của ArrayIterator. ArrayIterator cho phép lặp một object trong vòng lặp nhiều lần giống như một arrray. Vì chúng ta đã khởi tạo một thể hiện của ArrayIterator ở constructor, nên trong hàm getIterator chúng ta chỉ cần return $this->items là xong.

Tới đây, chúng ta đã có thể sử dụng colection trong vòng lặp. Tuy nhiên, collection vẫn là một object, muốn truy cập vào các thuộc tính của nó như một array, chúng ta phải implements ArrayAccess. interface này yêu cầu các methods offsetGet, offsetSet, offsetUnset, offsetUnset:

 /** * @param string $key * @return mixed */ public function offsetGet($key) { return $this->items[$key]; }

Hàm offsetGet được gọi khi chúng ta get một thuộc tính của object(ở đây là class Collection của chúng ta) như một array. VD: $collection['key1'], $collection['key2'] Khi đó, chúng ta sẽ return giá trị được chứ trong $this->items.

/** * @return void */
public function offsetSet($key, $value)
{ if (is_null($key)) { $this->items[] = $value; } else { $this->items[$key] = $value; }
}

Hàm offsetSet được gọi khi chúng ta gán một giá trị cho collection. VD: $collection['key1'] = ''key1"; Khi đó, chúng ta sẽ gán giá trị truyền vào cho $this->items.

/** * @return void */
public function offsetUnset($key)
{ unset($this->items[$key]);
}

Hàm offsetUnset sẽ được gọi khi chúng ta sử dụng hàm unset. VD: unset($collection['key1']). Tương tự, chúng ta cũng sẽ gọi hàm unset với $this->items.

/** * Determine if an item exists at an offset. * * @param TKey $key * @return bool */
public function offsetExists($key)
{ return isset($this->items[$key]);
}

Hàm offsetExists sẽ được gọi khi chúng ta gọi hàm isset để kiểm tra một key. Khi đó chúng ta sẽ gọi hàm isset để kiểm tra key trong $this->items.

2. Các phương thức bổ trợ Như chúng ta thấy, các thao tác với collection đều sử dụng $this->items, một instance của ArrayIterator. Tuy nhiên chúng ta lại không thể gọi các phương thức của ArrayIterator trong một thể hiện của collection. Hàm sau đây sẽ giải quyết điều đó:

public function __call($name, $arguments)
{ if (method_exists($this->items, $name)) { return call_user_func_array([$this->items, $name], $arguments); }
}

Hàm sẽ được kích hoạt khi gọi các phương thức không thể truy cập trong collection. Khi đó, chúng ta sẽ kiểm tra xem method đó có trong $this->items hay không, nếu có thì return method trong $this->items.

Chúng ta cũng có thể thêm các phương thức để collection có thể sử dụng giống một array hơn. VD

public function pop()
{ $arrayItems = iterator_to_array($this->items); $results = array_pop($arrayItems); $this->items = new ArrayIterator($arrayItems); return $results;
}

3. Test Cuối cùng, chúng ta tạo một file php để test collection.

$a = new Collection(['a', 'b', 'c']);
echo $a[0]; // return 'a'
$a[4] = '4'; // thêm phần tử vào collection
$c = isset($a[4]); //return true
unset($a[4]);// unset phần tử ra khỏi collection
$a->pop();// return 'c'
foreach($a as $key => &$value) { // sử dụng collection trong vòng lặp echo "$key => $value<br>";
}
$a->append('foobar');// gọi hàm append trong ArrayIterator để thêm phần tử vào cuối collection

Đây là lần đầu viết bài, không thể tránh khỏi các sai sót. Mong được mọi người chỉ bảo thêm. Xin chân thành cảm ơn 😃)

.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Cài đặt WSL / WSL2 trên Windows 10 để code như trên Ubuntu

Sau vài ba năm mình chuyển qua code trên Ubuntu thì thật không thể phủ nhận rằng mình đã yêu em nó. Cá nhân mình sử dụng Ubuntu để code web thì thật là tuyệt vời.

0 0 409

- vừa được xem lúc

Phân quyền đơn giản với package Laravel permission

Như các bạn đã biết, phân quyền trong một ứng dụng là một phần không thể thiếu trong việc phát triển phần mềm, dù đó là ứng dụng web hay là mobile. Vậy nên, hôm nay mình sẽ giới thiệu một package có thể giúp các bạn phân quyền nhanh và đơn giản trong một website được viết bằng PHP với framework là L

0 0 462

- vừa được xem lúc

Sử dụng Swagger để xây dựng API documentation

Giới thiệu về Swagger. RESTful API là một tiêu chuẩn dùng trong việc thiết kế API cho các ứng dụng web (thiết kế Web services) để tiện cho việc quản lý các resource.

0 0 1k

- vừa được xem lúc

So sánh Interface và Abstract trong lập trình hướng đối tượng.

Tổng quan. Interface và Abstract class là 2 khái niệm cơ bản trong lập trình OOP.

0 0 63

- vừa được xem lúc

CURL và cách sử dụng trong PHP

Giới Thiệu. CURL là bộ thư viện được sử dụng để giúp thực hiện việc chuyển dữ liệu thông qua nhiều giao thức khác nhau (như HTTP, FPT...). Với giao thức HTTP, cURL hỗ trợ việc gửi dữ liệu sử dụng tất cả các phương thức hiện có như GET, POST, PUT, DELETE... cURL cũng hỗ trợ việc chuyền dữ liệu sử dụn

0 0 93

- vừa được xem lúc

Thêm dòng dữ liệu mới (MySQL) trong Laravel

Chào các bạn, Laravel hiện đang là hot trend trong "thế giới PHP". 1. Cấu hình cơ bản ban đầu. .

0 0 51