Topic 9: Using Other Open-Source Material
📖 5 min read · 🎯 advanced · 🧭 Prerequisites: navigation, socket-io-the-front-end-and-a-chat-app
Why this matters
Here's the thing — when you're building a real PHP project, you don't have to write everything from scratch. The open-source world is full of libraries that smart developers have already built, tested, and battle-hardened. Tools like Composer, Smarty, Laravel, and PHPUnit exist precisely so you don't reinvent the wheel every time. But knowing a library exists and knowing how to bring it into your project safely — that's a different skill. In this lesson, we'll learn exactly how to find, integrate, and trust open-source material without losing control of your own codebase.
What You'll Learn
- Why open-source libraries exist and when to trust them
- How to discover PHP packages on Packagist, GitHub, and SourceForge
- How to integrate Smarty, Laravel, and PHPUnit via Composer
- How to run a rendered Smarty template, a Laravel route, and a PHPUnit test suite
The Analogy
Think of open-source libraries as specialist contractors hired by a general contractor (you). You don't need to know how to wire every electrical circuit yourself — you hire an electrician who has already passed inspections, earned community trust, and fixed their own bugs over years of real-world projects. Composer is your project management office: it tracks every contractor's name, version, and dependencies so nobody shows up twice or at the wrong time. You focus on designing the building; the contractors handle the details they've already mastered.
Chapter 1: Why Use Open-Source Materials?
Open-source resources — libraries, frameworks, testing tools — accelerate PHP development because the hard problems have already been solved and battle-tested by thousands of contributors. The core advantages are:
- Cost-Effective — free to use, modify, and distribute under open licenses
- Community Support — large communities provide extensive documentation, Stack Overflow answers, and active issue trackers
- Quality and Security — rigorously tested codebases with public vulnerability disclosures and quick patches
- Innovation — access to cutting-edge features (typed properties, async patterns, modern ORM abstractions) without building them from scratch
Chapter 2: Finding Open-Source Libraries and Tools
Three platforms cover the vast majority of PHP open-source discovery:
| Platform | What it is | Best for |
|---|---|---|
| Packagist | Default package repository for Composer | Searching versioned PHP packages by name or keyword |
| GitHub | Largest general-purpose open-source host | Browsing source, reading issues, finding unmaintained packages |
| SourceForge | Older repository of open-source software | Legacy PHP projects and downloads |
For any modern PHP project, start on Packagist — every package there is installable with a single composer require command.
Chapter 3: Example 1 — Smarty Template Engine
Smarty separates the presentation layer from the application logic layer, letting designers work on .tpl files without touching PHP.
Step 1 — Install Smarty via Composer
composer require smarty/smarty
Step 2 — Set Up the Directory Structure
my_project/
├── templates/
│ └── index.tpl
├── templates_c/
└── index.php
templates_c/ is Smarty's compile cache directory — it must be writable by the web server.
Step 3 — Create the Template File (templates/index.tpl)
<!DOCTYPE html>
<html>
<head>
<title>{$title}</title>
</head>
<body>
<h1>{$heading}</h1>
<p>{$content}</p>
</body>
</html>
Step 4 — Create the PHP Entry Point (index.php)
<?php
require 'vendor/autoload.php';
$smarty = new Smarty;
$smarty->setTemplateDir('./templates');
$smarty->setCompileDir('./templates_c');
$smarty->assign('title', 'Smarty Example');
$smarty->assign('heading', 'Hello, Smarty!');
$smarty->assign('content', 'This is a simple example of using Smarty.');
$smarty->display('index.tpl');
?>
Step 5 — Run the Built-in PHP Server
php -S localhost:8000
Open your browser at http://localhost:8000 to see the rendered template with variables injected from PHP into the .tpl file.
Chapter 4: Example 2 — Laravel Framework
Laravel is a full-featured PHP framework known for its elegant syntax, expressive ORM (Eloquent), and batteries-included feature set (queues, events, authentication scaffolding, and more).
Step 1 — Create a New Laravel Project via Composer
composer create-project --prefer-dist laravel/laravel my_laravel_project
Step 2 — Navigate to the Project Directory
cd my_laravel_project
Step 3 — Serve the Application
php artisan serve
Open http://localhost:8000 to see the default Laravel welcome page.
Step 4 — Add a Custom Route
Edit routes/web.php:
<?php
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome', ['name' => 'Laravel']);
});
Step 5 — Update the Blade View
Edit resources/views/welcome.blade.php:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to {{ $name }}</title>
</head>
<body>
<h1>Hello, {{ $name }}!</h1>
</body>
</html>
Blade's {{ $name }} syntax auto-escapes output to prevent XSS — a free security win over raw echo.
Step 6 — Refresh the Browser
Visit http://localhost:8000 — the view now renders "Hello, Laravel!" using the variable passed from the route closure.
Chapter 5: Example 3 — PHPUnit for Testing
PHPUnit is the standard testing framework for PHP. It provides assertions, test doubles (mocks/stubs), and a CLI runner that integrates with CI pipelines.
Step 1 — Install PHPUnit as a Dev Dependency
composer require --dev phpunit/phpunit
The --dev flag keeps PHPUnit out of production installs.
Step 2 — Create the Project Structure
my_project/
├── src/
│ └── Calculator.php
└── tests/
└── CalculatorTest.php
Step 3 — Write a Simple Class to Test (src/Calculator.php)
<?php
class Calculator {
public function add($a, $b) {
return $a + $b;
}
}
Step 4 — Write the PHPUnit Test (tests/CalculatorTest.php)
<?php
use PHPUnit\Framework\TestCase;
class CalculatorTest extends TestCase {
public function testAdd() {
$calculator = new Calculator();
$result = $calculator->add(2, 3);
$this->assertEquals(5, $result);
}
}
assertEquals(expected, actual) is the workhorse assertion — it fails with a clear diff when the values don't match.
Step 5 — Run the Test Suite
vendor/bin/phpunit tests
PHPUnit outputs a dot (.) per passing test, F for failures, and E for errors. A green run means your Calculator::add() method behaves as specified.
Chapter 6: Putting It Together — The Dependency Lifecycle
flowchart LR
A[Find package on Packagist] --> B[composer require vendor/package]
B --> C[composer.json updated]
C --> D[vendor/ directory populated]
D --> E[require vendor/autoload.php]
E --> F[Use the library in PHP code]
F --> G{Ship to production}
G --> H[composer install --no-dev]
The key discipline: never commit vendor/ — commit composer.json and composer.lock instead. Your teammates and CI server run composer install to reconstruct the exact dependency tree from the lock file.
🧪 Try It Yourself
Task: Add PHPUnit to a new PHP project and write a test for a Multiplier class.
- Create a new directory and initialize Composer:
mkdir example-math && cd example-math
composer init --no-interaction
composer require --dev phpunit/phpunit
mkdir src tests
- Create
src/Multiplier.php:
<?php
class Multiplier {
public function multiply($a, $b) {
return $a * $b;
}
}
- Create
tests/MultiplierTest.php:
<?php
use PHPUnit\Framework\TestCase;
class MultiplierTest extends TestCase {
public function testMultiply() {
$m = new Multiplier();
$this->assertEquals(12, $m->multiply(3, 4));
}
}
- Run it:
vendor/bin/phpunit tests
Success criterion: You see OK (1 test, 1 assertion) in green. If you see a red FAILED, check your arithmetic in the multiply method.
🔍 Checkpoint Quiz
Q1. Why should PHPUnit be installed with --dev rather than as a regular dependency?
A) It runs faster when flagged as dev
B) It is excluded from production installs, keeping the vendor footprint smaller
C) Composer cannot version-lock dev packages
D) PHPUnit only works inside the tests/ directory
Q2. Given this Smarty setup, what does $smarty->assign('heading', 'Hello, Smarty!') do?
$smarty->assign('heading', 'Hello, Smarty!');
$smarty->display('index.tpl');
A) Writes the string directly to stdout
B) Stores the value so {$heading} in the template renders as Hello, Smarty!
C) Sets an HTTP response header
D) Creates a PHP variable named $heading in global scope
Q3. What is the purpose of composer.lock and why should it be committed to version control?
A) It prevents Composer from downloading packages
B) It records the exact resolved versions of every dependency so all environments install identical code
C) It stores your Packagist API credentials
D) It is a binary cache file generated per-machine and should be gitignored
Q4. A teammate adds a new Laravel route but the browser still shows the old page after a refresh. Which of these is the most likely cause?
Route::get('/about', function () {
return view('about');
});
A) The view('about') call should be view('about.blade.php')
B) The resources/views/about.blade.php file does not exist yet
C) Laravel routes require a controller — closures are not supported
D) php artisan serve must be restarted after every route change
A1. B — --dev marks the package as a development dependency; composer install --no-dev (used on production servers) skips it entirely, reducing attack surface and install time.
A2. B — assign() registers a key-value pair in Smarty's internal context. When display() compiles and renders the template, every {$heading} placeholder is replaced with the assigned value.
A3. B — composer.lock pins the exact version (including transitive dependencies) resolved at the time of composer update. Committing it ensures every developer and CI environment installs the same code, eliminating "works on my machine" version drift.
A4. B — Laravel's view('about') looks for resources/views/about.blade.php. If that file does not exist, Laravel throws a View [about] not found exception. Routes using closures are perfectly valid; the server does not need a restart for route changes.
🪞 Recap
- Open-source libraries save time, improve security, and let you ship features that would take months to build from scratch.
- Packagist is the canonical PHP package registry; Composer manages installation, versioning, and autoloading.
- Smarty cleanly separates template markup from PHP logic using
assign()anddisplay(). - Laravel's
composer create-projectscaffolds a full MVC framework in one command, with Blade handling safe variable interpolation. - PHPUnit tests are plain PHP classes extending
TestCase; run them withvendor/bin/phpunit testsand watch for green dots.
📚 Further Reading
- Packagist — browse and search the full PHP package ecosystem
- Smarty Documentation — complete Smarty template syntax reference
- Laravel Documentation — the official guide covering routing, Blade, Eloquent, and beyond
- PHPUnit Documentation — assertions, test doubles, and CI integration
- Composer Documentation — dependency resolution, scripts, and lock file semantics
- ⬅️ Previous: Socket.IO — The Front End and a Chat App
- ➡️ Next: Introduction to Redux