PHPのコレクションオブジェクト
15626 ワード
配列の問題
PHPでは、配列は非常に柔軟なデータ構造です.これはほとんどすべてを受け入れ、好きなように組み合わせることができます.これは実際に良いです:他の言語とは異なり、PHPでは、連想配列と数字の配列を組み合わせることができますので、自由を提供します.しかし、あなたがちょうどタイプ安全性を必要とする時があります.
それに対処する一つの方法はきっと、配列のすべての項目をチェックすることです.
$array = [1,2,3,4,5]
foreach ($array as $item) {
if (!is_int($item)) {
throw new \Exception('wrong type');
}
//do your stuff here
}
これは明らかに機能していますが、ちょっと奇妙です.解決策:コレクション
コレクションは、配列をあなたのために要約するクラスです.基本的なコレクションクラスは次のようになります.
class IntCollection {
private $values = [];
public function addValue (int $val, $key = null): void
{
//the typehint ensures that you won't have any non-integer values
if ($key === null) {
$this->values[] = $val;
} else {
$this->values[$key] = $val;
}
}
public function deleteValue($key): void
{
unset($this->values[$key]);
}
public function get($key): int
{
return $this->values[$key];
}
}
それは既にかなりクールですが、十分ではありません.例えば、より良い解決策
幸いにも、PHPは我々にツールを提供します.このために、コア言語インターフェイスのいくつかを使用するために、コレクションクラスをリファクタにする必要があります.
インターフェイスは、クラスのAPI定義です.インターフェイスを実装する場合は、クラスが特定の標準化された定義済みの方法で動作することを世界に伝えます.あなたが初めてそれを見るとき、それは「抽象クラスのように」あなたを攻撃するかもしれません、しかし、それは全く正しくありません
Countable => クラスを' count () 'のような関数で使用できるようにします
Iterator => あなたのオブジェクトが
ArrayAccess => これを実装し、配列のようなコレクションを使用することができます(例えば$ collection [$ key ])
class IntCollection implements \Countable, \Iterator, \ArrayAccess
{
private $values = [];
private $position = 0;
/**
* This constructor is there in order to be able to create a collection with
* its values already added
*/
public function __construct(array $values = [])
{
foreach ($values as $value) {
$this->offsetSet('', $value);
}
}
/**
* Implementation of method declared in \Countable.
* Provides support for count()
*/
public function count()
{
return count($this->values);
}
/**
* Implementation of method declared in \Iterator
* Resets the internal cursor to the beginning of the array
*/
public function rewind()
{
$this->position = 0;
}
/**
* Implementation of method declared in \Iterator
* Used to get the current key (as for instance in a foreach()-structure
*/
public function key()
{
return $this->position;
}
/**
* Implementation of method declared in \Iterator
* Used to get the value at the current cursor position
*/
public function current()
{
return $this->values[$this->position];
}
/**
* Implementation of method declared in \Iterator
* Used to move the cursor to the next position
*/
public function next()
{
$this->position++;
}
/**
* Implementation of method declared in \Iterator
* Checks if the current cursor position is valid
*/
public function valid()
{
return isset($this->values[$this->position]);
}
/**
* Implementation of method declared in \ArrayAccess
* Used to be able to use functions like isset()
*/
public function offsetExists($offset)
{
return isset($this->values[$offset]);
}
/**
* Implementation of method declared in \ArrayAccess
* Used for direct access array-like ($collection[$offset]);
*/
public function offsetGet($offset)
{
return $this->values[$offset];
}
/**
* Implementation of method declared in \ArrayAccess
* Used for direct setting of values
*/
public function offsetSet($offset, $value)
{
if (!is_int($value)) {
throw new \InvalidArgumentException("Must be an int");
}
if (empty($offset)) { //this happens when you do $collection[] = 1;
$this->values[] = $value;
} else {
$this->values[$offset] = $value;
}
}
/**
* Implementation of method declared in \ArrayAccess
* Used for unset()
*/
public function offsetUnset($offset)
{
unset($this->values[$offset]);
}
}
より良い解決策:SPLの使用
The SPL あなたが見ているならば、あなたが多くの非常に役に立つものを見つけるPHPからの中心的なライブラリです.残念ながら、それが有用であるように、それはほとんど広く知られていません.ここでの問題については、ArrayObjectというクラスが含まれています.これは、以前に手で行ったもの全てをシリアル化しています.オブジェクトを拡張することで、私たちの最終コレクションクラスは文字通り時間通りに書かれます.
class IntCollection extends \ArrayObject
{
public function offsetSet($index, $newval)
{
if (!is_int($newval)) {
throw new \InvalidArgumentException("Must be int");
}
parent::offsetSet($index, $newval);
}
}
Reference
この問題について(PHPのコレクションオブジェクト), 我々は、より多くの情報をここで見つけました https://dev.to/fahrenholz/collection-objects-in-php-1cbkテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol