Skip to content

Instantly share code, notes, and snippets.

@Kcko
Last active March 20, 2020 08:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kcko/ab7c142d14de9efe2e38106a353f2329 to your computer and use it in GitHub Desktop.
Save Kcko/ab7c142d14de9efe2e38106a353f2329 to your computer and use it in GitHub Desktop.
<?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
);
<?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);
}
<?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