SlideShare a Scribd company logo
May the 4th
PHP CollectionsImage by statefarm
• Object Relationships…
• Perfect for One-To-Many Joins…
• Traditionally just arrays which were good…
WHY?
• No rules about what is stored in the array…
• No rules about how to store/retrieve…
• Often public…
• No separation of concerns…
• Arrays are by default passed byValue…
• Array[‘Notation’]…
WHATS WRONG WITH ARRAYS?
• Easy to use…
• Easy to add, access, remove items…
• Easy to traverse/loop…
• How many array_ functions are there?…
WHAT WAS RIGHT WITH ARRAYS?
• It’s a “bucket” of objects
• So, essentially, it’s a wrapper for an array…
• But encapsulated with rules…
• We can control the indexes…
• We know more about the content types…
• It can have non-member properties
WHAT IS A COLLECTION CLASS?
• private $items = array(); // property…
• traversable…
• countable…
• Other Interfaces?

e.g. JsonSerializable() or toJSON()
ATTRIBUTES OF A COLLECTION CLASS
• Arrays are mutable…
• Collection Classes are often mutable…
• mutability is a choice to be made early on…
• The Immutable class is lightweight…
MUTABILITY
• with function addItem(FixedType $item){}…
• we now have type checking
• adding individual elements
MUTABILITY &TYPE CHECKING
• Only one way an object can be immutable…

• __construct($items){

					$this->items	=	$items

}	
• It is fixed after instantiation, no setItems / addItems
methods…
IMMUTABILITY &TYPE CHECKING
SOME CODE
// the old way

Class Artist {



public $albums = array();



private $name;



public function __construct($name) {

$this->name = $name;

}



}



$artist = new Artist('Prince');

$artist->albums[] = '1999';

$artist->albums[] = 'Purple Rain';

Class Artist {



private $albums = array();



private $name;



public function __construct($name) {

$this->name = $name;

}



public function addItem($item) {

$this->albums[] = $item;

}



}



$artist = new Artist('Prince');

$artist->addItem[] = 'Purple Rain';
Class Artist {



/**

* @var AlbumCollection

*/

private $albums;





public function setAlbums($albums)

{

$this->albums = $albums;

}



//...

}





Class AlbumCollection {



private $items = array();



public function addItem(Album $album) {

$this->items[] = $album;

}



}
// Using the Collection Class


$artist = new Artist('Prince');



// Build The Album Collection

$albums = new AlbumCollection();
// Note we add Album types

$albums->addItem( new Album('1999') );

$albums->addItem( new Album(‘Purple Rain') );

$albums->addItem( new Album(‘Sign O The Times') );



// Set the Collection as an Artist property

$artist->setAlbums($albums);
WHAT ABOUT

COUNTABLE 

TRAVERSABLE

…
Class AlbumCollection implements IteratorAggregate ,
Countable {



private $items = array();



public function addItem(Album $album) {

$this->items[] = $album;

}



// Implement Traversable (Iterator Aggregate) 

// Interface

public function getIterator() {

return new ArrayIterator($this->items);

}



// Implement Countable Interface

public function count() {

return count($this->items);

}



}
• Our app will contain more than one collection…
• Remember DRY principles…
• Don’t copy/paste the interface implementations…
ABSTRACT FOR PORTABLITY
abstract Class BaseCollection implements
Countable, IteratorAggregate 

{

private $items = array();



// Implement Traversable via
// IteratorAggregate Interface

public function getIterator() {

return new ArrayIterator($this->items);

}



// Implement Countable Interface

public function count() {

return count($this->items);

}



}

// An Artist has many Albums

Class AlbumCollection extends BaseCollection {



private $items = array();



public function addItem(Album $album) {

$this->items[] = $album;

}



}



// Albums have many Songs

Class SongCollection extends BaseCollection {



private $items = array();



public function addItem(Song $song) {

$this->items[] = $song;

}



}
class Artist {



// @var AlbumCollection

protected $albums;



// @var SongCollection

protected $songs;



// @var TourCollection

protected $concerts;



// MetadataCollection

protected $metadata;



// GenreCollection;

protected $genres;



// Tags Collection

protected $tags;



}
COLLECTING THE DOTS…



WHAT ABOUTTHE DOTS..?
PHP Belfast |  Collection Classes
• Pass an indeterminate number of parameters…
• Can pack a list of arguments…
• Can unpack an array to a list of arguments…
• Can be used in the function call or definition…
• So…
PHP5.6+ HASTHE …TOKEN

THEVARIABLE LENGTHTOKEN
bit.ly/VarL3nT0k
WITH IT WE CAN CREATE

STRONGLY TYPED ARRAYS


Class AlbumCollection extends BaseCollection {



private $items = array();
// Strongly typed, unknown length
// All items passed must be of type Album
public function __construct(Album ...$albums)

{

$this->items = $albums;

}



}



$batman = new Album('Batman');

$purple = new Album('Purple Rain’);
// this works, but it’s messy

$albums = new AlbumCollection($batman, $purple);



Class AlbumCollection extends BaseCollection {



//…



}

// we can create an array of Albums

// or foreach through a DB powered list
$Albums[] = new Album('Batman');

$Albums[] = new Album('Purple Rain’);
$Albums[] = new Album('Dirty Mind');

$Albums[] = new Album('Diamonds and Pearls');

// this wont work

$collection = new AlbumCollection($Albums);

// this WILL work, using ‘…’ to unpack the Array

$collection = new AlbumCollection(…$Albums);

• We are now portable thanks to our abstract
collection
• We are strongly typed
• We are decoupled, each type and collection can
be independently tested
PORTABLE &TESTABLE
• IteratorAggregate Interface as a minimum
• extend ArrayObject

implements IteratorAggregate,ArrayAccess, Serializable, Countable
• Only implement the functionality that you 

will use/need
USETHE SPL…
• Add commonly used functionlaity to your base
class
• e.g. findBy($property,	$value)

BUILD ONYOUR BASE
public function findBy($property, $value)

{

// look for an accessor method e.g. getTitle()
$method = “get" . ucwords($property);
foreach ($this->items as $key => $obj) {
if (method_exists($obj, $method) {
if ($obj->{$method}() == $property) {
return($obj);
}
}
}


}
BUILD ONYOUR CONCRETE CLASS


Class SongCollection extends BaseCollection {



protected $items;



// each song has a duration, 

// collection has a total duration

private $totalDuration;



public function getTotalDuration()

{

$totalDuration= 0;

foreach($this->items as $song) {

$totalDuration += $song->duration;

}

}



}
• Many Frameworks, especially ORM components
have their own Collection implementations
• If you use a Framework investigate the options

Doctrine ArrayCollection, IlluminateSupportCollection
• If you aren’t using a framework…

…Learn from the Frameworks
A FINAL WORD ON FRAMEWORKS
T H A N K Y O U

More Related Content

What's hot (18)

PDF
The Origin of Lithium
Nate Abele
 
PPT
Php Using Arrays
mussawir20
 
PDF
The Zen of Lithium
Nate Abele
 
PDF
Laravel collections an overview - Laravel SP
Matheus Marabesi
 
PPT
Php array
Core Lee
 
PDF
Php array
Nikul Shah
 
PDF
Arrays in PHP
Vineet Kumar Saini
 
PDF
Refactoring using Codeception
Jeroen van Dijk
 
PDF
Be RESTful (Symfony Camp 2008)
Fabien Potencier
 
PDF
Marc’s (bio)perl course
Marc Logghe
 
PDF
jQuery - Introdução
Gustavo Dutra
 
PDF
Symfony components in the wild, PHPNW12
Jakub Zalas
 
KEY
Keeping It Small with Slim
Raven Tools
 
KEY
Lithium Best
Richard McIntyre
 
PDF
Dades i operadors
Alex Muntada Duran
 
PDF
Drupal is Stupid (But I Love It Anyway)
brockboland
 
PDF
Dependency injection-zendcon-2010
Fabien Potencier
 
PDF
PHP 5.3 and Lithium: the most rad php framework
G Woo
 
The Origin of Lithium
Nate Abele
 
Php Using Arrays
mussawir20
 
The Zen of Lithium
Nate Abele
 
Laravel collections an overview - Laravel SP
Matheus Marabesi
 
Php array
Core Lee
 
Php array
Nikul Shah
 
Arrays in PHP
Vineet Kumar Saini
 
Refactoring using Codeception
Jeroen van Dijk
 
Be RESTful (Symfony Camp 2008)
Fabien Potencier
 
Marc’s (bio)perl course
Marc Logghe
 
jQuery - Introdução
Gustavo Dutra
 
Symfony components in the wild, PHPNW12
Jakub Zalas
 
Keeping It Small with Slim
Raven Tools
 
Lithium Best
Richard McIntyre
 
Dades i operadors
Alex Muntada Duran
 
Drupal is Stupid (But I Love It Anyway)
brockboland
 
Dependency injection-zendcon-2010
Fabien Potencier
 
PHP 5.3 and Lithium: the most rad php framework
G Woo
 

Similar to PHP Belfast | Collection Classes (20)

PDF
Iterators, ArrayAccess & Countable (Oh My!) - Madison PHP 2014
Sandy Smith
 
PDF
Laravelcollectionsunraveled
Renato Lucena
 
PDF
Banishing Loops with Functional Programming in PHP
David Hayes
 
KEY
Spl Not A Bridge Too Far phpNW09
Michelangelo van Dam
 
PDF
Object Oriented Programming in PHP
Lorna Mitchell
 
PDF
OOPs Concept
Mohammad Yousuf
 
PPTX
Arrays in PHP
davidahaskins
 
PPTX
FFW Gabrovo PMG - PHP OOP Part 3
Toni Kolev
 
PDF
Typed Properties and more: What's coming in PHP 7.4?
Nikita Popov
 
PPT
OOP
thinkphp
 
DOC
Cool Object Building With PHP
wensheng wei
 
PPTX
Creating a Single View Part 2: Loading Disparate Source Data and Creating a S...
MongoDB
 
PPT
An Elephant of a Different Colour: Hack
Vic Metcalfe
 
PPTX
Php meetup 20130912 reflection
JoelRSimpson
 
PDF
Decoupling Objects With Standard Interfaces
Thomas Weinert
 
PDF
Advanced Php - Macq Electronique 2010
Michelangelo van Dam
 
KEY
Intermediate PHP
Bradley Holt
 
PDF
0php 5-online-cheat-sheet-v1-3
Fafah Ranaivo
 
PPTX
OOP Is More Than Cars and Dogs
Chris Tankersley
 
KEY
Can't Miss Features of PHP 5.3 and 5.4
Jeff Carouth
 
Iterators, ArrayAccess & Countable (Oh My!) - Madison PHP 2014
Sandy Smith
 
Laravelcollectionsunraveled
Renato Lucena
 
Banishing Loops with Functional Programming in PHP
David Hayes
 
Spl Not A Bridge Too Far phpNW09
Michelangelo van Dam
 
Object Oriented Programming in PHP
Lorna Mitchell
 
OOPs Concept
Mohammad Yousuf
 
Arrays in PHP
davidahaskins
 
FFW Gabrovo PMG - PHP OOP Part 3
Toni Kolev
 
Typed Properties and more: What's coming in PHP 7.4?
Nikita Popov
 
Cool Object Building With PHP
wensheng wei
 
Creating a Single View Part 2: Loading Disparate Source Data and Creating a S...
MongoDB
 
An Elephant of a Different Colour: Hack
Vic Metcalfe
 
Php meetup 20130912 reflection
JoelRSimpson
 
Decoupling Objects With Standard Interfaces
Thomas Weinert
 
Advanced Php - Macq Electronique 2010
Michelangelo van Dam
 
Intermediate PHP
Bradley Holt
 
0php 5-online-cheat-sheet-v1-3
Fafah Ranaivo
 
OOP Is More Than Cars and Dogs
Chris Tankersley
 
Can't Miss Features of PHP 5.3 and 5.4
Jeff Carouth
 
Ad

Recently uploaded (20)

PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PPTX
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
PDF
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
PDF
July Patch Tuesday
Ivanti
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PDF
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
PDF
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
PDF
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
PPTX
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
PDF
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
PDF
From Code to Challenge: Crafting Skill-Based Games That Engage and Reward
aiyshauae
 
PPTX
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
PDF
Timothy Rottach - Ramp up on AI Use Cases, from Vector Search to AI Agents wi...
AWS Chicago
 
PDF
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
PDF
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
PDF
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
July Patch Tuesday
Ivanti
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
From Code to Challenge: Crafting Skill-Based Games That Engage and Reward
aiyshauae
 
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
Timothy Rottach - Ramp up on AI Use Cases, from Vector Search to AI Agents wi...
AWS Chicago
 
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
Ad

PHP Belfast | Collection Classes

  • 1. May the 4th PHP CollectionsImage by statefarm
  • 2. • Object Relationships… • Perfect for One-To-Many Joins… • Traditionally just arrays which were good… WHY?
  • 3. • No rules about what is stored in the array… • No rules about how to store/retrieve… • Often public… • No separation of concerns… • Arrays are by default passed byValue… • Array[‘Notation’]… WHATS WRONG WITH ARRAYS?
  • 4. • Easy to use… • Easy to add, access, remove items… • Easy to traverse/loop… • How many array_ functions are there?… WHAT WAS RIGHT WITH ARRAYS?
  • 5. • It’s a “bucket” of objects • So, essentially, it’s a wrapper for an array… • But encapsulated with rules… • We can control the indexes… • We know more about the content types… • It can have non-member properties WHAT IS A COLLECTION CLASS?
  • 6. • private $items = array(); // property… • traversable… • countable… • Other Interfaces?
 e.g. JsonSerializable() or toJSON() ATTRIBUTES OF A COLLECTION CLASS
  • 7. • Arrays are mutable… • Collection Classes are often mutable… • mutability is a choice to be made early on… • The Immutable class is lightweight… MUTABILITY
  • 8. • with function addItem(FixedType $item){}… • we now have type checking • adding individual elements MUTABILITY &TYPE CHECKING
  • 9. • Only one way an object can be immutable…
 • __construct($items){
 $this->items = $items
 } • It is fixed after instantiation, no setItems / addItems methods… IMMUTABILITY &TYPE CHECKING
  • 11. // the old way
 Class Artist {
 
 public $albums = array();
 
 private $name;
 
 public function __construct($name) {
 $this->name = $name;
 }
 
 }
 
 $artist = new Artist('Prince');
 $artist->albums[] = '1999';
 $artist->albums[] = 'Purple Rain';

  • 12. Class Artist {
 
 private $albums = array();
 
 private $name;
 
 public function __construct($name) {
 $this->name = $name;
 }
 
 public function addItem($item) {
 $this->albums[] = $item;
 }
 
 }
 
 $artist = new Artist('Prince');
 $artist->addItem[] = 'Purple Rain';
  • 13. Class Artist {
 
 /**
 * @var AlbumCollection
 */
 private $albums;
 
 
 public function setAlbums($albums)
 {
 $this->albums = $albums;
 }
 
 //...
 }
 
 
 Class AlbumCollection {
 
 private $items = array();
 
 public function addItem(Album $album) {
 $this->items[] = $album;
 }
 
 }
  • 14. // Using the Collection Class 
 $artist = new Artist('Prince');
 
 // Build The Album Collection
 $albums = new AlbumCollection(); // Note we add Album types
 $albums->addItem( new Album('1999') );
 $albums->addItem( new Album(‘Purple Rain') );
 $albums->addItem( new Album(‘Sign O The Times') );
 
 // Set the Collection as an Artist property
 $artist->setAlbums($albums);
  • 16. Class AlbumCollection implements IteratorAggregate , Countable {
 
 private $items = array();
 
 public function addItem(Album $album) {
 $this->items[] = $album;
 }
 
 // Implement Traversable (Iterator Aggregate) 
 // Interface
 public function getIterator() {
 return new ArrayIterator($this->items);
 }
 
 // Implement Countable Interface
 public function count() {
 return count($this->items);
 }
 
 }
  • 17. • Our app will contain more than one collection… • Remember DRY principles… • Don’t copy/paste the interface implementations… ABSTRACT FOR PORTABLITY
  • 18. abstract Class BaseCollection implements Countable, IteratorAggregate 
 {
 private $items = array();
 
 // Implement Traversable via // IteratorAggregate Interface
 public function getIterator() {
 return new ArrayIterator($this->items);
 }
 
 // Implement Countable Interface
 public function count() {
 return count($this->items);
 }
 
 }

  • 19. // An Artist has many Albums
 Class AlbumCollection extends BaseCollection {
 
 private $items = array();
 
 public function addItem(Album $album) {
 $this->items[] = $album;
 }
 
 }
 
 // Albums have many Songs
 Class SongCollection extends BaseCollection {
 
 private $items = array();
 
 public function addItem(Song $song) {
 $this->items[] = $song;
 }
 
 }
  • 20. class Artist {
 
 // @var AlbumCollection
 protected $albums;
 
 // @var SongCollection
 protected $songs;
 
 // @var TourCollection
 protected $concerts;
 
 // MetadataCollection
 protected $metadata;
 
 // GenreCollection;
 protected $genres;
 
 // Tags Collection
 protected $tags;
 
 }
  • 23. • Pass an indeterminate number of parameters… • Can pack a list of arguments… • Can unpack an array to a list of arguments… • Can be used in the function call or definition… • So… PHP5.6+ HASTHE …TOKEN
 THEVARIABLE LENGTHTOKEN bit.ly/VarL3nT0k
  • 24. WITH IT WE CAN CREATE
 STRONGLY TYPED ARRAYS
  • 25. 
 Class AlbumCollection extends BaseCollection {
 
 private $items = array(); // Strongly typed, unknown length // All items passed must be of type Album public function __construct(Album ...$albums)
 {
 $this->items = $albums;
 }
 
 }
 
 $batman = new Album('Batman');
 $purple = new Album('Purple Rain’); // this works, but it’s messy
 $albums = new AlbumCollection($batman, $purple);

  • 26. 
 Class AlbumCollection extends BaseCollection {
 
 //…
 
 }
 // we can create an array of Albums
 // or foreach through a DB powered list $Albums[] = new Album('Batman');
 $Albums[] = new Album('Purple Rain’); $Albums[] = new Album('Dirty Mind');
 $Albums[] = new Album('Diamonds and Pearls');
 // this wont work
 $collection = new AlbumCollection($Albums);
 // this WILL work, using ‘…’ to unpack the Array
 $collection = new AlbumCollection(…$Albums);

  • 27. • We are now portable thanks to our abstract collection • We are strongly typed • We are decoupled, each type and collection can be independently tested PORTABLE &TESTABLE
  • 28. • IteratorAggregate Interface as a minimum • extend ArrayObject
 implements IteratorAggregate,ArrayAccess, Serializable, Countable • Only implement the functionality that you 
 will use/need USETHE SPL…
  • 29. • Add commonly used functionlaity to your base class • e.g. findBy($property, $value)
 BUILD ONYOUR BASE public function findBy($property, $value)
 {
 // look for an accessor method e.g. getTitle() $method = “get" . ucwords($property); foreach ($this->items as $key => $obj) { if (method_exists($obj, $method) { if ($obj->{$method}() == $property) { return($obj); } } } 
 }
  • 30. BUILD ONYOUR CONCRETE CLASS 
 Class SongCollection extends BaseCollection {
 
 protected $items;
 
 // each song has a duration, 
 // collection has a total duration
 private $totalDuration;
 
 public function getTotalDuration()
 {
 $totalDuration= 0;
 foreach($this->items as $song) {
 $totalDuration += $song->duration;
 }
 }
 
 }
  • 31. • Many Frameworks, especially ORM components have their own Collection implementations • If you use a Framework investigate the options
 Doctrine ArrayCollection, IlluminateSupportCollection • If you aren’t using a framework…
 …Learn from the Frameworks A FINAL WORD ON FRAMEWORKS
  • 32. T H A N K Y O U