Lesson 5
Data Manipulation Techniques in PHP
Introduction to Data Manipulation

Welcome to our lesson on practical data manipulation techniques using PHP! In this lesson, we will explore how to manipulate data structures with PHP's arrays and associative arrays. Our operations will be conveniently bundled within a PHP class, offering clean and organized code. Let's get our tools ready and dive into data manipulation in PHP.

Here's a simple PHP class, DataStream, that will be our toolbox for handling data:

php
1<?php 2 3class DataStream { 4 private $data; 5 6 public function __construct(array $data) { 7 $this->data = $data; 8 } 9} 10 11?>
Data Projection in Practice

Our first stop is data projection, where we focus on extracting specific details from our dataset. Suppose we have data about people and we are interested in only names and ages. We will extend our DataStream class with a project method that uses PHP's array_map to accomplish this task:

php
1<?php 2 3class DataStream { 4 private $data; 5 6 public function __construct(array $data) { 7 $this->data = $data; 8 } 9 10 public function project(callable $projectFunc): DataStream { 11 $projectedData = array_map($projectFunc, $this->data); 12 return new DataStream($projectedData); 13 } 14 15 public function printData(): void { 16 foreach ($this->data as $entry) { 17 echo join(', ', array_map( 18 fn($value, $key) => "$key: $value", 19 $entry, 20 array_keys($entry) 21 )) . "\n"; 22 } 23 } 24} 25 26$data = [ 27 ['name' => 'Alice', 'age' => '25', 'profession' => 'Engineer'], 28 ['name' => 'Bob', 'age' => '30', 'profession' => 'Doctor'] 29]; 30 31$ds = new DataStream($data); 32 33$projectedDs = $ds->project(function($entry) { 34 return ['name' => $entry['name'], 'age' => $entry['age']]; 35}); 36 37$projectedDs->printData(); 38// Outputs: 39// name: Alice, age: 25 40// name: Bob, age: 30 41 42?>
Data Filtering in Practice

Next, we focus on filtering data to select specific entries. We'll extend our DataStream class with a filter method that leverages PHP's array_filter using anonymous functions:

php
1<?php 2 3class DataStream { 4 private $data; 5 6 public function __construct(array $data) { 7 $this->data = $data; 8 } 9 10 public function project(callable $projectFunc): DataStream { 11 $projectedData = array_map($projectFunc, $this->data); 12 return new DataStream($projectedData); 13 } 14 15 public function filter(callable $testFunc): DataStream { 16 $filteredData = array_filter($this->data, $testFunc); 17 return new DataStream($filteredData); 18 } 19 20 public function printData(): void { 21 foreach ($this->data as $entry) { 22 echo join(', ', array_map( 23 fn($value, $key) => "$key: $value", 24 $entry, 25 array_keys($entry) 26 )) . "\n"; 27 } 28 } 29} 30 31$data = [ 32 ['name' => 'Alice', 'age' => '25', 'profession' => 'Engineer'], 33 ['name' => 'Bob', 'age' => '30', 'profession' => 'Doctor'] 34]; 35 36$ds = new DataStream($data); 37 38$ageTest = function($entry) { 39 return (int)$entry['age'] > 26; 40}; 41 42$filteredDs = $ds->filter($ageTest); 43$filteredDs->printData(); 44// Outputs: 45// name: Bob, age: 30, profession: Doctor 46 47?>
Data Aggregation in Practice

Finally, we turn to data aggregation to summarize data. We will use PHP's built-in functions to achieve this within our DataStream class. Here's how we can compute the average age, for example:

php
1<?php 2 3class DataStream { 4 private $data; 5 6 public function __construct(array $data) { 7 $this->data = $data; 8 } 9 10 public function project(callable $projectFunc): DataStream { 11 $projectedData = array_map($projectFunc, $this->data); 12 return new DataStream($projectedData); 13 } 14 15 public function filter(callable $testFunc): DataStream { 16 $filteredData = array_filter($this->data, $testFunc); 17 return new DataStream($filteredData); 18 } 19 20 public function aggregate(string $key, callable $aggFunc): float { 21 $values = array_map(fn($entry) => $entry[$key], $this->data); 22 return $aggFunc($values); 23 } 24 25 public function printData(): void { 26 foreach ($this->data as $entry) { 27 echo join(', ', array_map( 28 fn($value, $key) => "$key: $value", 29 $entry, 30 array_keys($entry) 31 )) . "\n"; 32 } 33 } 34} 35 36$data = [ 37 ['name' => 'Alice', 'age' => '25', 'profession' => 'Engineer'], 38 ['name' => 'Bob', 'age' => '30', 'profession' => 'Doctor'] 39]; 40 41$ds = new DataStream($data); 42 43$averageAgeCalculator = function($ages) { 44 $sum = array_sum(array_map('intval', $ages)); 45 return $sum / count($ages); 46}; 47 48$averageAge = $ds->aggregate('age', $averageAgeCalculator); 49echo $averageAge; // Outputs: 27.5 50 51?>
Combining Projection, Filtering, and Aggregation

Now, let's see how to combine these powerful techniques using PHP. Our example will demonstrate the workflow:

  1. Data Projection: Select specific fields.
  2. Data Filtering: Apply conditions to filter data.
  3. Data Aggregation: Compute a summary statistic.

Here's how you can implement this combination in PHP:

php
1<?php 2 3class DataStream { 4 private $data; 5 6 public function __construct(array $data) { 7 $this->data = $data; 8 } 9 10 public function project(callable $projectFunc): DataStream { 11 $projectedData = array_map($projectFunc, $this->data); 12 return new DataStream($projectedData); 13 } 14 15 public function filter(callable $testFunc): DataStream { 16 $filteredData = array_filter($this->data, $testFunc); 17 return new DataStream($filteredData); 18 } 19 20 public function aggregate(string $key, callable $aggFunc): float { 21 $values = array_map(fn($entry) => $entry[$key], $this->data); 22 return $aggFunc($values); 23 } 24 25 public function printData(): void { 26 foreach ($this->data as $entry) { 27 echo join(', ', array_map( 28 fn($value, $key) => "$key: $value", 29 $entry, 30 array_keys($entry) 31 )) . "\n"; 32 } 33 } 34} 35 36$data = [ 37 ['name' => 'Alice', 'age' => '25', 'profession' => 'Engineer', 'salary' => '70000'], 38 ['name' => 'Bob', 'age' => '30', 'profession' => 'Doctor', 'salary' => '120000'], 39 ['name' => 'Carol', 'age' => '35', 'profession' => 'Artist', 'salary' => '50000'], 40 ['name' => 'David', 'age' => '40', 'profession' => 'Engineer', 'salary' => '90000'] 41]; 42 43$ds = new DataStream($data); 44 45// Step 1: Project to include 'name', 'age', 'salary' 46$projectedDs = $ds->project(function($entry) { 47 return [ 48 'name' => $entry['name'], 49 'age' => $entry['age'], 50 'salary' => $entry['salary'] 51 ]; 52}); 53 54// Step 2: Filter where age > 30 55$filteredDs = $projectedDs->filter(function($entry) { 56 return (int)$entry['age'] > 30; 57}); 58 59// Step 3: Aggregate to compute average salary 60$averageSalaryCalculator = function($salaries) { 61 $total = array_sum(array_map('intval', $salaries)); 62 return $total / count($salaries); 63}; 64 65$averageSalary = $filteredDs->aggregate('salary', $averageSalaryCalculator); 66echo $averageSalary; // Outputs: 70000 67 68?>
Lesson Summary

Congratulations! You've now learned the basics of data projection, filtering, and aggregation utilizing PHP arrays and their associative forms. You've seen how to package these processes in a PHP class for efficient and reusable code. Now, why not try some practice exercises to apply these skills? You're well-equipped to handle data manipulation with PHP. Happy coding!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.