Last active
March 20, 2020 08:05
-
-
Save Kcko/ab7c142d14de9efe2e38106a353f2329 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 | |
class Book | |
{ | |
private string $author; | |
private string $title; | |
public function __construct(string $title, string $author) | |
{ | |
$this->author = $author; | |
$this->title = $title; | |
} | |
public function getAuthor(): string | |
{ | |
return $this->author; | |
} | |
public function getTitle(): string | |
{ | |
return $this->title; | |
} | |
public function getAuthorAndTitle(): string | |
{ | |
return $this->getTitle().' by '.$this->getAuthor(); | |
} | |
} | |
use Countable; | |
use Iterator; | |
class BookList implements Countable, Iterator | |
{ | |
/** | |
* @var Book[] | |
*/ | |
private array $books = []; | |
private int $currentIndex = 0; | |
public function addBook(Book $book) | |
{ | |
$this->books[] = $book; | |
} | |
public function removeBook(Book $bookToRemove) | |
{ | |
foreach ($this->books as $key => $book) { | |
if ($book->getAuthorAndTitle() === $bookToRemove->getAuthorAndTitle()) { | |
unset($this->books[$key]); | |
} | |
} | |
$this->books = array_values($this->books); | |
} | |
public function count(): int | |
{ | |
return count($this->books); | |
} | |
public function current(): Book | |
{ | |
return $this->books[$this->currentIndex]; | |
} | |
public function key(): int | |
{ | |
return $this->currentIndex; | |
} | |
public function next() | |
{ | |
$this->currentIndex++; | |
} | |
public function rewind() | |
{ | |
$this->currentIndex = 0; | |
} | |
public function valid(): bool | |
{ | |
return isset($this->books[$this->currentIndex]); | |
} | |
} | |
// USAGE | |
$book = new Book('Clean Code', 'Robert C. Martin'); | |
$book2 = new Book('Professional Php Design Patterns', 'Aaron Saray'); | |
$bookList = new BookList(); | |
$bookList->addBook($book); | |
$bookList->addBook($book2); | |
$bookList->removeBook($book); | |
$books = []; | |
foreach ($bookList as $book) { | |
$books[] = $book->getAuthorAndTitle(); | |
} | |
$this->assertSame( | |
['Professional Php Design Patterns by Aaron Saray'], | |
$books | |
); |
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 | |
/** | |
* CSV File Iterator. | |
* | |
* @author Josh Lockhart | |
*/ | |
class CsvIterator implements \Iterator | |
{ | |
const ROW_SIZE = 4096; | |
/** | |
* The pointer to the CSV file. | |
* | |
* @var resource | |
*/ | |
protected $filePointer = null; | |
/** | |
* The current element, which is returned on each iteration. | |
* | |
* @var array | |
*/ | |
protected $currentElement = null; | |
/** | |
* The row counter. | |
* | |
* @var int | |
*/ | |
protected $rowCounter = null; | |
/** | |
* The delimiter for the CSV file. | |
* | |
* @var string | |
*/ | |
protected $delimiter = null; | |
/** | |
* The constructor tries to open the CSV file. It throws an exception on | |
* failure. | |
* | |
* @param string $file The CSV file. | |
* @param string $delimiter The delimiter. | |
* | |
* @throws \Exception | |
*/ | |
public function __construct($file, $delimiter = ',') | |
{ | |
try { | |
$this->filePointer = fopen($file, 'rb'); | |
$this->delimiter = $delimiter; | |
} catch (\Exception $e) { | |
throw new \Exception('The file "' . $file . '" cannot be read.'); | |
} | |
} | |
/** | |
* This method resets the file pointer. | |
*/ | |
public function rewind(): void | |
{ | |
$this->rowCounter = 0; | |
rewind($this->filePointer); | |
} | |
/** | |
* This method returns the current CSV row as a 2-dimensional array. | |
* | |
* @return array The current CSV row as a 2-dimensional array. | |
*/ | |
public function current(): array | |
{ | |
$this->currentElement = fgetcsv($this->filePointer, self::ROW_SIZE, $this->delimiter); | |
$this->rowCounter++; | |
return $this->currentElement; | |
} | |
/** | |
* This method returns the current row number. | |
* | |
* @return int The current row number. | |
*/ | |
public function key(): int | |
{ | |
return $this->rowCounter; | |
} | |
/** | |
* This method checks if the end of file has been reached. | |
* | |
* @return bool Returns true on EOF reached, false otherwise. | |
*/ | |
public function next(): bool | |
{ | |
if (is_resource($this->filePointer)) { | |
return !feof($this->filePointer); | |
} | |
return false; | |
} | |
/** | |
* This method checks if the next row is a valid row. | |
* | |
* @return bool If the next row is a valid row. | |
*/ | |
public function valid(): bool | |
{ | |
if (!$this->next()) { | |
if (is_resource($this->filePointer)) { | |
fclose($this->filePointer); | |
} | |
return false; | |
} | |
return true; | |
} | |
} | |
/** | |
* The client code. | |
*/ | |
$csv = new CsvIterator(__DIR__ . '/cats.csv'); | |
foreach ($csv as $key => $row) { | |
print_r($row); | |
} |
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 | |
class Employee { | |
public $name; | |
public $position; | |
public function __construct (string $name, string $position) { | |
$this->name = $name; | |
$this->position = $position; | |
} | |
} | |
use SplObjectStorage, IteratorAggregate, Countable; | |
class CompanyEmployeeTeam implements IteratorAggregate, Countable { | |
public $person; | |
private $subordinates; | |
public function __construct (Employee $person) { | |
$this->subordinates = new SplObjectStorage(); | |
$this->person = $person; | |
} | |
public function addSubordinate (CompanyEmployeeTeam $subordinate): void { | |
$this->subordinates->attach($subordinate); | |
} | |
public function removeSubordinate (CompanyEmployeeTeam $subordinate): void { | |
$this->subordinates->detach($subordinate); | |
} | |
public function getSubordinates (): SplObjectStorage { | |
return $this->subordinates; | |
} | |
public function getIterator (): EmployeeTeamIterator { | |
return new EmployeeTeamIterator($this); | |
} | |
public function count (): int { | |
return count(new EmployeeTeamIterator($this)); | |
} | |
public function getName (): string { | |
return $this->person->name; | |
} | |
public function getPosition (): string { | |
return $this->person->position; | |
} | |
} | |
use Iterator, Countable; | |
class EmployeeTeamIterator implements Iterator, Countable { | |
private $position = 0; | |
private $teamMembers = []; | |
public function __construct (CompanyEmployeeTeam $employee) { | |
$this->addTeam($employee); | |
$this->position = 0; | |
} | |
protected function addTeam (CompanyEmployeeTeam $employee): void { | |
foreach ($employee->getSubordinates() as $member) { | |
array_push($this->teamMembers, $member); | |
$this->addTeam($member); | |
} | |
} | |
public function current (): CompanyEmployeeTeam { | |
return $this->teamMembers[$this->position]; | |
} | |
public function next (): void { | |
++$this->position; | |
} | |
public function key (): int { | |
return $this->position; | |
} | |
public function valid (): bool { | |
return isset($this->teamMembers[$this->position]); | |
} | |
public function rewind (): void { | |
$this->position = 0; | |
} | |
public function count (): int { | |
return count($this->teamMembers); | |
} | |
} | |
// USAGE | |
$john = new CompanyEmployeeTeam(new Employee("John", 'Director')); | |
$tom = new CompanyEmployeeTeam(new Employee("Tom", 'Developer')); | |
$johny = new CompanyEmployeeTeam(new Employee("Johny", 'Developer')); | |
$ceo = new CompanyEmployeeTeam(new Employee("Mark", "CEO")); | |
$john->addSubordinate($tom); | |
$john->addSubordinate($johny); | |
$ceo->addSubordinate($john); | |
showTeam($ceo); | |
$jan = new CompanyEmployeeTeam(new Employee("Jan", 'Developer')); | |
$ceo->addSubordinate($jan); | |
showTeam($ceo); | |
$ceo->removeSubordinate($jan); | |
showTeam($ceo); | |
function showTeam ($users) { | |
foreach ($users as $user) { | |
echo $user->getPosition() . ": " . $user->getName() . PHP_EOL; | |
} | |
echo "Number of subordinates of " . $users->getName() . ": " . count($users) . PHP_EOL; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment