Project Goal
It's time to put everything together! In this workshop, we will build a mini content publishing system from scratch. This project will use every OOP concept we've learned so far: Encapsulation, Inheritance, Abstract Classes, Interfaces, Traits, Namespaces, and Autoloading. Our goal is to manage different types of content, like an Article
and a Video
, using a professional, organized structure.
Step 1: Project Setup (Namespaces & Autoloading)
First, let's define our project structure. Create the following folders and files. This structure is common in modern PHP applications.
your-project/
├── src/
│ ├── Concerns/
│ │ └── HasAuthor.php
│ ├── Contracts/
│ │ └── Publishable.php
│ ├── Content/
│ │ ├── Content.php
│ │ ├── Article.php
│ │ └── Video.php
├── vendor/
├── composer.json
└── index.php
Next, create your composer.json
file and add the PSR-4 autoloading configuration:
{
"name": "your/oop-workshop",
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
Now, run composer dump-autoload
in your terminal. This generates the vendor/autoload.php
file that will handle loading all our classes automatically.
Step 2: Create a Reusable Trait (HasAuthor)
Let's create a trait to manage author information. This functionality can be "mixed in" to any class that needs an author.
File: src/Concerns/HasAuthor.php
<?php
namespace App\Concerns;
trait HasAuthor
{
protected $author;
public function setAuthor($name)
{
$this->author = $name;
}
public function getAuthor()
{
return $this->author ?? 'No author';
}
}
Step 3: Define a Contract (Publishable Interface)
This interface will be our "contract." It guarantees that any class that implements it will have a publish()
method.
File: src/Contracts/Publishable.php
<?php
namespace App\Contracts;
interface Publishable
{
public function publish();
}
Step 4: Build the Blueprint (Abstract Content Class)
This abstract class will be the "parent" for all our content types. It will contain the shared logic and properties. It cannot be instantiated by itself.
File: src/Content/Content.php
<?php
namespace App\Content;
use App\Concerns\HasAuthor;
use App\Contracts\Publishable;
abstract class Content implements Publishable
{
use HasAuthor; // Use the trait here!
protected $title;
public function __construct($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
// By implementing the interface, we MUST define this method.
public function publish()
{
return "Publishing content titled '{$this->title}' by {$this->getAuthor()}.";
}
// Define an abstract method that all child classes MUST implement.
abstract public function getSummary();
}
Step 5: Create Concrete Classes (Article & Video)
These are our specific content types. They will inherit from the abstract Content
class and provide their own unique implementation for the getSummary()
method.
File: src/Content/Article.php
<?php
namespace App\Content;
class Article extends Content
{
public function getSummary()
{
return "This is an article titled '{$this->getTitle()}'.";
}
}
File: src/Content/Video.php
<?php
namespace App\Content;
class Video extends Content
{
public function getSummary()
{
return "This is a video about '{$this->getTitle()}'.";
}
}
Step 6: Putting It All Together!
Finally, let's use our new OOP system in our main index.php
file.
File: index.php
<?php
require_once 'vendor/autoload.php';
use App\Content\Article;
use App\Content\Video;
// Create a new Article
$article = new Article('My First OOP Article');
$article->setAuthor('John Doe');
// Create a new Video
$video = new Video('PHP for Beginners');
$video->setAuthor('Jane Smith');
// --- Display the results ---
echo '
' . $article->getSummary() . '
';
echo '
' . $article->publish() . '
';
echo '
';
echo '
' . $video->getSummary() . '
';
echo '
' . $video->publish() . '
';
When you run index.php
, you will see how all the pieces work together perfectly, thanks to the power of OOP!
Conclusion & What You've Learned
Congratulations! You have successfully built a small but professional PHP application. In this workshop, you have used:
- Namespaces and Autoloading to organize and load files.
- A Trait (
HasAuthor
) to reuse code across different classes. - An Interface (
Publishable
) to define a required capability. - An Abstract Class (
Content
) to act as a shared parent blueprint. - Inheritance (
Article extends Content
) to create specialized child classes. - Polymorphism, as both
Article
andVideo
provided their own unique version ofgetSummary()
.