Skip to content

Instantly share code, notes, and snippets.

@42milez
Last active August 29, 2015 14:27
Show Gist options
  • Save 42milez/827d5bf082862edd4a65 to your computer and use it in GitHub Desktop.
Save 42milez/827d5bf082862edd4a65 to your computer and use it in GitHub Desktop.
<?php
/* Aug. 21, 2015 - Akihiro TAKASE
*
* 以下は Standard PHP Library の ArrayIterator を利用したサンプルコードです。
* Employee オブジェクトの配列が Department オブジェクトのプライベートプロパティとなっています。
* 本サンプルでは当該配列を ArrayIterator を利用して走査します。
*
*/
// Employee クラスへアクセッサを提供するトレイト
trait EmployeeAccessors {
public function __call($method, $args) {
// - 正規表現にマッチする場合に OR 演算子の後方を遅延評価する
// - アクセッサのプリフィックスと対象プロパティ名はそれぞれ accessor、property をキーとして連想配列に格納する
if (!preg_match('/(?P<accessor>set|get)(?P<property>[A-Z][a-zA-Z0-9]*)/', $method, $match) ||
!property_exists(__CLASS__, $match['property'] = lcfirst($match['property'])))
{
// 未定義プロパティに対するアクセスは例外として扱う
throw new BadMethodCallException(sprintf("'%s' does not exist in '%s'.", $method, get_class(__CLASS__)));
}
switch ($match['accessor']) {
case 'get':
return $this->{$match['property']};
case 'set':
if (!$args) {
throw new InvalidArgumentException(sprintf("'%s' requires an argument value.", $method));
}
$this->{$match['property']} = $args[0];
return $this;
}
}
}
// Department クラスへアクセッサを提供するトレイト
trait DepartmentAccessors {
public function __call($method, $args) {
if (!preg_match('/(?P<accessor>addTo|set|get)(?P<property>[A-Z][a-zA-Z0-9]*)/', $method, $match) ||
!property_exists(__CLASS__, $match['property'] = lcfirst($match['property'])))
{
throw new BadMethodCallException(sprintf("'%s' does not exist in '%s'.", $method, get_class(__CLASS__)));
}
switch ($match['accessor']) {
case 'get':
return $this->{$match['property']};
case 'set':
if (!$args) {
throw new InvalidArgumentException(sprintf("'%s' requires an argument value.", $method));
}
if (get_class($this->{$match['property']}) === 'ArrayObject') {
throw new BadMethodCallException("Accessing array with SET accessor is prohibited.");
}
else {
$this->{$match['property']} = $args[0];
}
return $this;
case 'addTo':
if (!$args) {
throw new InvalidArgumentException(sprintf("'%s' requires an argument value.", $method));
}
$this->{$match['property']}[] = $args[0];
return $this;
}
}
}
// 社員クラス
class Employee {
use EmployeeAccessors;
private $id = ''; // 社員ID
private $firstName = ''; // 姓
private $givenName = ''; // 名
private $email = ''; // メールアドレス
function __construct($id, $firstName, $givenName, $email) {
$this->id = $id;
$this->firstName = $firstName;
$this->givenName = $givenName;
$this->email = $email;
}
}
// 部署クラス
class Department {
use DepartmentAccessors;
private $name = ''; // 部署名
private $employees = NULL;
function __construct($name) {
$this->name = $name;
$this->employees = new ArrayObject();
}
function getEmployeesIterator() {
return new ArrayIterator($this->employees);
}
}
$prd = new Department('Public Relations Department');
try {
$prd->addToEmployees(new Employee('0000000001', 'Kevin', 'Cooper', 'kevin.cooper@dayrep.com'));
$prd->addToEmployees(new Employee('0000000002', 'Ana', 'Tyler', 'ana.tyler@dayrep.com'));
$prd->addToEmployees(new Employee('0000000003', 'John', 'Monroy', 'john.monroy@dayrep.com'));
$prd->addToEmployees(new Employee('0000000004', 'Era', 'Draper', 'era.draper@dayrep.com'));
$prd->addToEmployees(new Employee('0000000005', 'Florence', 'Brown', 'florence.brown@dayrep.com'));
}
catch (Exception $e) {
// exception handling
// ...
}
// イテレーターを利用して社員情報を列挙する
$it = $prd->getEmployeesIterator();
echo sprintf("[%s]\n", $prd->getName());
foreach($it as $key => $val) {
echo sprintf("ID: %s\n", $val->getId());
echo sprintf("Name: %s %s\n", $val->getFirstName(), $val->getGivenName());
echo sprintf("E-mail: %s\n", $val->getEmail());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment