Last active
August 29, 2015 14:27
-
-
Save 42milez/827d5bf082862edd4a65 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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', '[email protected]')); | |
$prd->addToEmployees(new Employee('0000000002', 'Ana', 'Tyler', '[email protected]')); | |
$prd->addToEmployees(new Employee('0000000003', 'John', 'Monroy', '[email protected]')); | |
$prd->addToEmployees(new Employee('0000000004', 'Era', 'Draper', '[email protected]')); | |
$prd->addToEmployees(new Employee('0000000005', 'Florence', 'Brown', '[email protected]')); | |
} | |
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