Traits and classes: worried about length of class - php

I am working on a web application in which I want registered users can access everything related to their account via a single class (member)
Like:
example.com/controller_class/action_name
example.com/member/my-profile,
example.com/member/edit-profile,
example.com/member/my-orders,
example.com/member/mybooks,
example.com/member/my-book-requests,
example.com/member/my-notes,
example.com/member/my-notes-requests
and so.
I am using traits in my PHP classes with having 500-600 lines in each trait. Now I am worried about the class length to compile. I have used 6-7 traits (or can be more in future) in a single class, and class code becomes around 5000 lines. Is there any effect on performance during compilation of class or any drawback of following such approach.
Style which I am following:
trait Profile {
...
}
trait books {
...
}
trait Services {
...
}
etc., and the main class is:
require_once 'traits/trait.Common.php';
require_once 'traits/trait.profile.php';
require_once 'traits/trait.books.php';
require_once 'traits/trait.services.php';
require_once 'traits/trait.notes.php';
require_once 'traits/trait.Account.php';
class MemberController extends LoggedUserController {
use Common, profile, books, services, notes, Account;
...
}
If I am on a wrong way, could you please suggest to me the best way to accomplish the same?
Thanks.

The actual impact on parsing performance should be negligible. However, purely from a design standpoint, you should split this up into multiple classes and use composition, or the Composite Pattern:
he composite pattern describes that a group of objects is to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects and compositions uniformly.
So, instead of traits, things like the "profile" should be objects of a class called MemberProfile, instantiated with information for this particular member. Inside Member, you could access something from the profile via $this->profile->getName(); or $this->profile->name;, for example.
Here's a quick example:
<?php
require_once 'MemberProfile.php';
require_once 'MemberAccount.php';
class MemberController extends LoggedUserController
{
public $profile;
public $account;
public function __construct()
{
$memberId = $_GET['memberId'];
$this->profile = new MemberProfile($memberId);
$this->account = new MemberAccount($memberId);
}
public function display()
{
$accountBalance = $this->account->getBalance();
$fullName = $this->profile->getFullName();
// ...
}
}

Related

How to properly structure and pass objects in a MVC structure in PHP

Over the past two years, I have become fairly familiar with PHP MVC style architecture, and have developed all my projects using MVC structures since then.
One question that has continued to bother me is how to group functions and database calls. I run into needing to perform the same actions across models. I would prefer not to duplicate these operations and sql query inside each of the models, but would rather group all user operations into a separate class.
For example, say I have a website with a forum, a blog, and a profile page, each with a separate model, view, and controller. However, say each of these pages needs to perform the same operation to the user table.
My Model class is constructed with a database object automatically. If I need to call a function from the user class, is it ok to pass the db object to that new User class? ... to do something like the following? I am not sure if passing objects like I am doing is fine, or is there a much better way of setting things up? Am I wasting resources, or is this a clumsy way of doing things?
Profile Model
class Profile_Model extends Model{
public function __construct() {
parent::__construct();
}
public function someFunction(){
$this->db->insert( "SOME SQL" );
$user = new User( $this->db ); // OK TO PASS DB OBJECT LIKE THIS?
$user->setSomething();
}
public function anotherFunction(){
//do something else that does not need a user object
}
}
User Class
class User{
public function __construct($db){
$this->db = $db; // OK TO SET DB OBJECT AS CLASS VARIABLE AGAIN?
}
public function setSomething(){
$this->db->insert( "SOME SQL" );
}
}
I'm trying to give you a really basic example of how I'd implement this architecture; Since it's really basic and I'm just a passionate developer and nothing more it could be I'm breaking some architectural rules, so please take it as a proof of concept.
LET'S START quickly with the Controller part where you get some request. Now you need someone that takes care of doing the dirty work.
As you can see here I'm trying to pass all the "dependencies" via constructor. These way you should be able to easily replace it with Mocks when testing .
Dependency injection is one of the concepts here.
AND NOW the Model (please remember Model is a layer and not a single class)
I've used "Services (or cases)" that should help you to compose a group of behaviors with all the actors (Classes) involved in this behavior.
Idendifying common behaviours that Services (or Cases) should do, is one of the concepts here.
Keep in mind that you should have a big picture in mind (or somewhere else depending on the project) before starting, in order to respect principle like KISS, SOLID, DRY, etc..
And please pay attention to method naming, often a bad or long name (like mine for example) is a sign that the class has more than a single Responsability or there's smell of bad design.
//App/Controllers/BlogController.php
namespace App\Controllers;
use App\Services\AuthServiceInterface;
use App\Services\BlogService;
use App\Http\Request;
use App\Http\Response;
class BlogController
{
protected $blogService;
public function __construct(AuthServiceInterface $authService, BlogService $blogService, Request $request)
{
$this->authService = $authService;
$this->blogService = $blogService;
$this->request = $request;
}
public function indexAction()
{
$data = array();
if ($this->authService->isAuthenticatedUser($this->request->getSomethingRelatedToTheUser())) {
$someData = $this->blogService->getSomeData();
$someOtherData = $this->request->iDontKnowWhatToDo();
$data = compact('someData', 'someOtherData');
}
return new Response($this->template, array('data' => $data), $status);
}
}
Now we need to create this Service that we've used in the controller. As you can see we're not talking directly with the "storage or data layer" but instead we're calling an abstraction layer that will handle that for us.
Using a Repository Pattern to retrieve data from a data layer, is one of the concepts here.
this way we can switch to whatever repository (inMemory, other storage, etc) to retrieve our data without changing the interface that the Controller is using, same method call but get data from another place.
Design by interfaces and not by concrete classes is one of the concepts here.
//App/Services/BlogService.php
<?php
namespace App\Services;
use App\Model\Repositories\BlogRepository;
class BlogService
{
protected $blogRepository;
public function __construct(BlogRepositoryInterface $blogRepository)
{
$this->blogRepository = $blogRepository;
}
public function getSomeData()
{
// do something complex with your data, here's just simple ex
return $this->blogRepository->findOne();
}
}
At this point we define the Repository that contains the persistance handler and knows about our Entity.
Again decoupling storage Persister and knowledge of an entity (what "can" be coupled with a mysql table for example), is one of the concepts here.
//App/Model/Repositories/BlogRepository.php
<?php
namespace App\Models\Respositories;
use App\Models\Entities\BlogEntity;
use App\Models\Persistance\DbStorageInterface;
class DbBlogRepository extends EntityRepository implements BlogRepositoryInterface
{
protected $entity;
public function __construct(DbStorageInterface $dbStorage)
{
$this->dbStorage = $dbStorage;
$this->entity = new BlogEntity;
}
public function findOne()
{
$data = $this->dbStorage->select('*')->from($this->getEntityName());
// This should be part of a mapping logic outside of here
$this->entity->setPropA($data['some']);
return $this->entity;
}
public function getEntityName()
{
return str_replace('Entity', '', get_class($this->entity));
}
}
At the end a simple entity with Setters and Getters:
//App/Model/Entities/BlogEntity.php
<?php
namespace App\Models\Entities;
class BlogEntity
{
protected $propA;
public function setPropA($dataA)
{
$this->propA = $dataA;
}
public function getPropA()
{
return $this->propA;
}
}
AND NOW? how can you inject this classes passed as dependencies? Well, this is a long answer.
Indicatively you could use Dependency Injection as we've done here have a init/boot file where you define things like:
// Laravel Style
App::bind('BlogRepositoryInterface', 'App\Model\Repositories\DbBlogRepository');
App::bind('DbStorageInterface', 'App\Model\Persistence\PDOStorage');
or some config/service.yml file like:
// Not the same but close to Symfony Style
BlogService:
class: "Namespace\\ConcreteBlogServiceClass"
Or you may feel the need of a Container Class from where you can ask the service you need to use in your controller.
function indexAction ()
{
$blogService = $this->container->getService('BlogService');
....
Dulcis in fundo here are some useful links (You can find tons of docs about this):
Services in Domain-Driven Design
Wicked Domain Model
Dependency Injection Container
Inversion of Control and Dependency Injection
Managing common Dependencies with parent Services
Whenever you need to use an object from another class there is only one safe way to do it: Dependency Injection.
Example:
Instead of having:
public function myMethod(){
$anotherObject = new Object();
}
You should inject the object with the constructor:
function __construct($dependency) {
$this->anotherObject = $dependency;
}
Once you have this structure you can use type hint and an Inversion of Control container to build thing automatically, e.g. define:
function __construct(DependencyInterface $dependency) {
$this->anotherObject = $dependency;
}
And then set your IoC container to inject the right dependency when you need to use this object
Do you use any frameworks? If not, try having a look at some popular ones, like Zend Framework or Symfony. You'll find they solve your problem and probably many more and are a great way to expand your knowledge on how to structure your project.
That aside you are close. Although adding the database directly to your User-model is probably not want you want to do. If you can get Martin Fowler's Patterns of Enterprise Application Architecture (PEAA) you will find a whole chapter outlining how to connect your models to your database. I prefer a Gateway-class (search for the Gateway-pattern or look at Zend_Db) when building something on my own, as it is relatively easy to implement and build.
Basically you have a class which performs queries and then will pass the data to your model. Just look at Data Source Architectural Patterns in Martin Fowler's pattern catalog (http://martinfowler.com/eaaCatalog/) to get a quick glance how to structure it and definitely read the book to get a real understanding when and how to use the patterns.
I hope this helps.
Part of the answer is to use dependency injection, but there is more to it than that. Cognitively speaking, grouping starts in the mind and is teased out better by brainstorming and modeling: Entity Relationship Diagrams and UML Diagrams.
Grouping of methods into classes and delegating tasks to injected objects makes sense, but there is usually room for one level of inheritance (at minimum). The use of abstract super classes and a Strategy Pattern for child classes that inherit base functionality from the abstract parent can help reduce code duplication (DRY).
All that being said, this is one reason why dependency injection containers are popular. They allow you to obtain the objects, and hence functionality, you need anywhere, without coupling object instantiation to usage.
Do a search for Pimple in Google. It may give you some ideas.

Organizing/extending classes in a PHP project

I'm working on a PHP project with a couple simple classes. I'm working on making my classes more complex, but I also wanted to start using classes for additional things like managing users, config settings, display, etc. I'm having a difficult time trying to figure out how to "organize" them. Like how should I extend these classes?
I have the following classes:
//main application settings, constants, etc.
Class Config {
}
//add/edit/delete/check permissions of users
Class Users extends Config {
}
//displays the pages
Class Display extends Config {
}
//main application
Class Analysis extends Config {
}
//specific methods for this type of analysis
Class Standard extends Analysis {
}
//specific methods for this type of analysis
Class Consolidated extends Analysis {
}
The issue I'm having is I want to be able to access the Users and Config classes from all the other classes (Display, Analysis, Standard, and Consolidated). How would I do this? Am I extending the classes properly? I feel like Display and Analysis should extend Users, but it doesn't seem right to me. I appreciate any help you can offer. Thanks!
In my projects my Users and Config classes are singleton classes which allows me to easily pull the instance into any other class with one simple method call.
Class User{
private static $_instance;
private function __construct(){
}
public function getInstance(){
if( !self::$_instance ){
self::$_instance = new User();
}
return self::$_instance;
}
}
Then wherever I need access to that user object
$user = User::getInstance();
You can try
trait Config {
}
// Common to Display
abstract class Display {
function __construct(Users $user);
}
// Common to analysis
abstract class Analysis {
function __construct(Users $user);
}
// add/edit/delete/check permissions of users
class Users {
use Config ;
}
// Mobile Display
class Mobile extends Display {
}
// Web Display
class Web extends Display {
}
// specific methods for this type of analysis
class Standard extends Analysis {
}
// specific methods for this type of analysis
class Consolidated extends Analysis {
}
// main application
class Main {
use Config ;
public function setDisplay(Display $display);
public function setAnalysis(Analysis $analysis);
}
$user = new Users("Jeff");
$main = new Main();
$main->setDisplay(new Mobile($user));
$main->setAnalysis(new Standard($user));
Keep them in separate files, and then use autoloading. Avoid the tendency to go OOP crazy. Remember that classes can be referenced as properties, not simply in an extension method.
As a general rule of thumb, you can use the "is-a" principle to organize your hierarchy of classes. For what you describe, it looks like:
Standard and Consolidated are (in the is-a sense) Analysis, so it looks like a good candidate for a hierarchy.
User and Display need to access the Config values, but they don't seem to be related in the conceptual way nor share common behavior, so it looks that composition is better suited than inheritance here.
Regarding the is-a principle you will generally recognize that it doesn't fit when the behavior that your subclass inherits doesn't belong to it. So, if for example your Config class has a saveValuesToDB() it definitely looks like something that the User shouldn't care about (i.e. how configuration values are stored in a DB). You can find a lot of information on the subject by searching for inheritance vs composition and is a recurrent subject in the pattern community. You can find a list of some good books about OO design and patterns here.
HTH

how to make inheritance optional

I'm currently helping build an API that I would like 3rd party developers to use. This API hooks to a service in the cloud. This service is constantly changing and not currently very reliable. Therefore, I would like to provide in my SDK both real clients and fake ones. Whenever the service is down, developers can simply use the fake client rather than the real one and continue coding.
I've looked at all sorts of design patterns and some addressed my problem nicely. Here is the catch though.. I want to make the code as simple as possible: So let's say my service is called Experia. I want people to be able to just do something like this:
class Experia extends Exp
...
$ex = new Experia(/*initialization parameters*/); //init prameters like user name, password etc
$ex->story()->create($storyArgs);
currently, Experia is a class that extends another class Exp that contains a list of these resources and the files they are available in.. and it also extends a generic class called Client that defines the basic get() and post() methods etc, and basically sets up the client remote url and so on (it wraps around the pest library)
so Exp goes something like this:
class Exp extends Client
{
public function story() {
include_once('classes/User.php');
}
//other resource methods
}
I want to create another class that contains all my fake resources.. something like this:
class ExpFake extends Client
{
public function story() {
include_once('classesFake/User.php');
}
//other resource methods
}
Here is the problem I'm facing. I want Experia to be able to extend either Exp or ExpFake depending on its declaration, without any ugliness.. and by ugliness I mean any extra code that developers using my API will have to use. So for example one thing I tried to do was decouple client from Exp and basically do this
$ex = new Experia(/*... */);
$ex->client = new fakeClient(); //I could also do $ex-> client = new realClient();
but then the problem was that every time I wanted to use call a resource.. I had to specify the client:
$this->client->story()->create($args)
the client part is extra code that i cannot include in my api..
so long story short.. what is the design pattern (or direct way if possible.. in php) that achieves the same result as selectively inheriting from one class or another
so like having the option of doing this:
class Experia extends (either Exp or ExpFake depending on Experia's initialization parameters)
A good way would be an adapter pattern. Your main client is the Exp class, which is what developers use to interact with your service. This class depends on an adapter to connect to your service though. This adapter class is required to be injected when instantiating Exp and is the part that can be mocked if necessary.
class Exp {
protected $adapter;
public function __construct(ExpAdapter $adapter) {
$this->adapter = $adapter;
}
public function foo() {
return $this->adapter->doFoo();
}
}
abstract class ExpAdapter {
abstract public function doFoo();
}
You can then create a real ExpAdapter and a mocked one:
class LiveExpAdapter extends ExpAdapter {
public function doFoo() {
// contact the actual service
}
}
class MockExpAdapter extends ExpAdapter {
public function doFoo() {
return true;
}
}
Instead of extending an abstract class, you can also use an interface specification.
To the developer, this will look like:
$exp = new Exp(new LiveExpAdapter);
// if service is down, use instead:
// $exp = new Exp(new MockExpAdapter);
$exp->foo();
depends on your php version, but I would use traits, in that case
trait Exp {
}
trait ExpFake {
}
class Experia {
use Exp;
}
alternative with drivers is fine as well e.g. define interface and separate drivers or implementations (as with db, when you have different driver classes e.g. mysql, psql etc)

Traits vs. interfaces

I've been trying to study up on PHP lately, and I find myself getting hung up on traits. I understand the concept of horizontal code reuse and not wanting to necessarily inherit from an abstract class. What I don't understand is: What is the crucial difference between using traits versus interfaces?
I've tried searching for a decent blog post or article explaining when to use one or the other, but the examples I've found so far seem so similar as to be identical.
Public Service Announcement:
I want to state for the record that I believe traits are almost always a code smell and should be avoided in favor of composition. It's my opinion that single inheritance is frequently abused to the point of being an anti-pattern and multiple inheritance only compounds this problem. You'll be much better served in most cases by favoring composition over inheritance (be it single or multiple). If you're still interested in traits and their relationship to interfaces, read on ...
Let's start by saying this:
Object-Oriented Programming (OOP) can be a difficult paradigm to grasp.
Just because you're using classes doesn't mean your code is
Object-Oriented (OO).
To write OO code you need to understand that OOP is really about the capabilities of your objects. You've got to think about classes in terms of what they can do instead of what they actually do. This is in stark contrast to traditional procedural programming where the focus is on making a bit of code "do something."
If OOP code is about planning and design, an interface is the blueprint and an object is the fully constructed house. Meanwhile, traits are simply a way to help build the house laid out by the blueprint (the interface).
Interfaces
So, why should we use interfaces? Quite simply, interfaces make our code less brittle. If you doubt this statement, ask anyone who's been forced to maintain legacy code that wasn't written against interfaces.
The interface is a contract between the programmer and his/her code. The interface says, "As long as you play by my rules you can implement me however you like and I promise I won't break your other code."
So as an example, consider a real-world scenario (no cars or widgets):
You want to implement a caching system for a web application to cut
down on server load
You start out by writing a class to cache request responses using APC:
class ApcCacher
{
public function fetch($key) {
return apc_fetch($key);
}
public function store($key, $data) {
return apc_store($key, $data);
}
public function delete($key) {
return apc_delete($key);
}
}
Then, in your HTTP response object, you check for a cache hit before doing all the work to generate the actual response:
class Controller
{
protected $req;
protected $resp;
protected $cacher;
public function __construct(Request $req, Response $resp, ApcCacher $cacher=NULL) {
$this->req = $req;
$this->resp = $resp;
$this->cacher = $cacher;
$this->buildResponse();
}
public function buildResponse() {
if (NULL !== $this->cacher && $response = $this->cacher->fetch($this->req->uri()) {
$this->resp = $response;
} else {
// Build the response manually
}
}
public function getResponse() {
return $this->resp;
}
}
This approach works great. But maybe a few weeks later you decide you want to use a file-based cache system instead of APC. Now you have to change your controller code because you've programmed your controller to work with the functionality of the ApcCacher class rather than to an interface that expresses the capabilities of the ApcCacher class. Let's say instead of the above you had made the Controller class reliant on a CacherInterface instead of the concrete ApcCacher like so:
// Your controller's constructor using the interface as a dependency
public function __construct(Request $req, Response $resp, CacherInterface $cacher=NULL)
To go along with that you define your interface like so:
interface CacherInterface
{
public function fetch($key);
public function store($key, $data);
public function delete($key);
}
In turn you have both your ApcCacher and your new FileCacher classes implement the CacherInterface and you program your Controller class to use the capabilities required by the interface.
This example (hopefully) demonstrates how programming to an interface allows you to change the internal implementation of your classes without worrying if the changes will break your other code.
Traits
Traits, on the other hand, are simply a method for re-using code. Interfaces should not be thought of as a mutually exclusive alternative to traits. In fact, creating traits that fulfill the capabilities required by an interface is the ideal use case.
You should only use traits when multiple classes share the same functionality (likely dictated by the same interface). There's no sense in using a trait to provide functionality for a single class: that only obfuscates what the class does and a better design would move the trait's functionality into the relevant class.
Consider the following trait implementation:
interface Person
{
public function greet();
public function eat($food);
}
trait EatingTrait
{
public function eat($food)
{
$this->putInMouth($food);
}
private function putInMouth($food)
{
// Digest delicious food
}
}
class NicePerson implements Person
{
use EatingTrait;
public function greet()
{
echo 'Good day, good sir!';
}
}
class MeanPerson implements Person
{
use EatingTrait;
public function greet()
{
echo 'Your mother was a hamster!';
}
}
A more concrete example: imagine both your FileCacher and your ApcCacher from the interface discussion use the same method to determine whether a cache entry is stale and should be deleted (obviously this isn't the case in real life, but go with it). You could write a trait and allow both classes to use it to for the common interface requirement.
One final word of caution: be careful not to go overboard with traits. Often traits are used as a crutch for poor design when unique class implementations would suffice. You should limit traits to fulfilling interface requirements for best code design.
An interface defines a set of methods that the implementing class must implement.
When a trait is use'd the implementations of the methods come along too--which doesn't happen in an Interface.
That is the biggest difference.
From the Horizontal Reuse for PHP RFC:
Traits is a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies.
A trait is essentially PHP's implementation of a mixin, and is effectively a set of extension methods which can be added to any class through the addition of the trait. The methods then become part of that class' implementation, but without using inheritance.
From the PHP Manual (emphasis mine):
Traits are a mechanism for code reuse in single inheritance languages such as PHP. ... It is an addition to traditional inheritance and enables horizontal composition of behavior; that is, the application of class members without requiring inheritance.
An example:
trait myTrait {
function foo() { return "Foo!"; }
function bar() { return "Bar!"; }
}
With the above trait defined, I can now do the following:
class MyClass extends SomeBaseClass {
use myTrait; // Inclusion of the trait myTrait
}
At this point, when I create an instance of class MyClass, it has two methods, called foo() and bar() - which come from myTrait. And - notice that the trait-defined methods already have a method body - which an Interface-defined method can't.
Additionally - PHP, like many other languages, uses a single inheritance model - meaning that a class can derive from multiple interfaces, but not multiple classes. However, a PHP class can have multiple trait inclusions - which allows the programmer to include reusable pieces - as they might if including multiple base classes.
A few things to note:
-----------------------------------------------
| Interface | Base Class | Trait |
===============================================
> 1 per class | Yes | No | Yes |
---------------------------------------------------------------------
Define Method Body | No | Yes | Yes |
---------------------------------------------------------------------
Polymorphism | Yes | Yes | No |
---------------------------------------------------------------------
Polymorphism:
In the earlier example, where MyClass extends SomeBaseClass, MyClass is an instance of SomeBaseClass. In other words, an array such as SomeBaseClass[] bases can contain instances of MyClass. Similarly, if MyClass extended IBaseInterface, an array of IBaseInterface[] bases could contain instances of MyClass. There is no such polymorphic construct available with a trait - because a trait is essentially just code which is copied for the programmer's convenience into each class which uses it.
Precedence:
As described in the Manual:
An inherited member from a base class is overridden by a member inserted by a Trait. The precedence order is that members from the current class override Trait methods, which in return override inherited methods.
So - consider the following scenario:
class BaseClass {
function SomeMethod() { /* Do stuff here */ }
}
interface IBase {
function SomeMethod();
}
trait myTrait {
function SomeMethod() { /* Do different stuff here */ }
}
class MyClass extends BaseClass implements IBase {
use myTrait;
function SomeMethod() { /* Do a third thing */ }
}
When creating an instance of MyClass, above, the following occurs:
The Interface IBase requires a parameterless function called SomeMethod() to be provided.
The base class BaseClass provides an implementation of this method - satisfying the need.
The trait myTrait provides a parameterless function called SomeMethod() as well, which takes precedence over the BaseClass-version
The class MyClass provides its own version of SomeMethod() - which takes precedence over the trait-version.
Conclusion
An Interface can not provide a default implementation of a method body, while a trait can.
An Interface is a polymorphic, inherited construct - while a trait is not.
Multiple Interfaces can be used in the same class, and so can multiple traits.
I think traits are useful to create classes that contain methods that can be used as methods of several different classes.
For example:
trait ToolKit
{
public $errors = array();
public function error($msg)
{
$this->errors[] = $msg;
return false;
}
}
You can have and use this "error" method in any class that uses this trait.
class Something
{
use Toolkit;
public function do_something($zipcode)
{
if (preg_match('/^[0-9]{5}$/', $zipcode) !== 1)
return $this->error('Invalid zipcode.');
// do something here
}
}
While with interfaces you can only declare the method signature, but not its functions' code. Also, to use an interface you need to follow a hierarchy, using implements. This is not the case with traits.
It is completely different!
For beginners above answer might be difficult, this is the easiest way to understand it:
Traits
trait SayWorld {
public function sayHello() {
echo 'World!';
}
}
so if you want to have sayHello function in other classes without re-creating the whole function you can use traits,
class MyClass{
use SayWorld;
}
$o = new MyClass();
$o->sayHello();
Cool right!
Not only functions you can use anything in the trait(function, variables, const...). Also, you can use multiple traits: use SayWorld, AnotherTraits;
Interface
interface SayWorld {
public function sayHello();
}
class MyClass implements SayWorld {
public function sayHello() {
echo 'World!';
}
}
So this is how interfaces differ from traits: You have to re-create everything in the interface in an implemented class. Interfaces don't have an implementation and interfaces can only have functions and constants, it cannot have variables.
I hope this helps!
Traits are simply for code reuse.
Interface just provides the signature of the functions that is to be defined in the class where it can be used depending on the programmer's discretion. Thus giving us a prototype for a group of classes.
For reference-
http://www.php.net/manual/en/language.oop5.traits.php
An often-used metaphor to describe Traits is Traits are interfaces with implementation.
This is a good way of thinking about it in most circumstances, but there are a number of subtle differences between the two.
For a start, the instanceof operator will not work with traits (ie, a trait is not a real object), therefore you can't use that to see if a class has a certain trait (or to see if two otherwise unrelated classes share a trait). That's what they mean by it being a construct for horizontal code re-use.
There are functions now in PHP that will let you get a list of all the traits a class uses, but trait-inheritance means you'll need to do recursive checks to reliably check if a class at some point has a specific trait (there's example code on the PHP doco pages). But yeah, it's certainly not as simple and clean as instanceof is, and IMHO it's a feature that would make PHP better.
Also, abstract classes are still classes, so they don't solve multiple-inheritance related code re-use problems. Remember you can only extend one class (real or abstract) but implement multiple interfaces.
I've found traits and interfaces are really good to use hand in hand to create pseudo multiple inheritance. Eg:
class SlidingDoor extends Door implements IKeyed
{
use KeyedTrait;
[...] // Generally not a lot else goes here since it's all in the trait
}
Doing this means you can use instanceof to determine if the particular Door object is Keyed or not, you know you'll get a consistent set of methods, etc, and all the code is in one place across all the classes that use the KeyedTrait.
You can consider a trait as an automated "copy-paste" of code, basically.
Using traits is dangerous since there is no mean to know what it does before execution.
However, traits are more flexible because of their lack of limitations such as inheritance.
Traits can be useful to inject a method which checks something into a class, for example, the existence of another method or attribute. A nice article on that (but in French, sorry).
For French-reading people who can get it, the GNU/Linux Magazine HS 54 has an article on this subject.
If you know English and know what trait means, it is exactly what the name says. It is a class-less pack of methods and properties you attach to existing classes by typing use.
Basically, you could compare it to a single variable. Closures functions can use these variables from outside of the scope and that way they have the value inside. They are powerful and can be used in everything. Same happens to traits if they are being used.
Other answers did a great job of explaining differences between interfaces and traits. I will focus on a useful real world example, in particular one which demonstrates that traits can use instance variables - allowing you add behavior to a class with minimal boilerplate code.
Again, like mentioned by others, traits pair well with interfaces, allowing the interface to specify the behavior contract, and the trait to fulfill the implementation.
Adding event publish / subscribe capabilities to a class can be a common scenario in some code bases. There's 3 common solutions:
Define a base class with event pub/sub code, and then classes which want to offer events can extend it in order to gain the capabilities.
Define a class with event pub/sub code, and then other classes which want to offer events can use it via composition, defining their own methods to wrap the composed object, proxying the method calls to it.
Define a trait with event pub/sub code, and then other classes which want to offer events can use the trait, aka import it, to gain the capabilities.
How well does each work?
#1 Doesn't work well. It would, until the day you realize you can't extend the base class because you're already extending something else. I won't show an example of this because it should be obvious how limiting it is to use inheritance like this.
#2 & #3 both work well. I'll show an example which highlights some differences.
First, some code that will be the same between both examples:
An interface
interface Observable {
function addEventListener($eventName, callable $listener);
function removeEventListener($eventName, callable $listener);
function removeAllEventListeners($eventName);
}
And some code to demonstrate usage:
$auction = new Auction();
// Add a listener, so we know when we get a bid.
$auction->addEventListener('bid', function($bidderName, $bidAmount){
echo "Got a bid of $bidAmount from $bidderName\n";
});
// Mock some bids.
foreach (['Moe', 'Curly', 'Larry'] as $name) {
$auction->addBid($name, rand());
}
Ok, now lets show how the implementation of the Auction class will differ when using traits.
First, here's how #2 (using composition) would look like:
class EventEmitter {
private $eventListenersByName = [];
function addEventListener($eventName, callable $listener) {
$this->eventListenersByName[$eventName][] = $listener;
}
function removeEventListener($eventName, callable $listener) {
$this->eventListenersByName[$eventName] = array_filter($this->eventListenersByName[$eventName], function($existingListener) use ($listener) {
return $existingListener === $listener;
});
}
function removeAllEventListeners($eventName) {
$this->eventListenersByName[$eventName] = [];
}
function triggerEvent($eventName, array $eventArgs) {
foreach ($this->eventListenersByName[$eventName] as $listener) {
call_user_func_array($listener, $eventArgs);
}
}
}
class Auction implements Observable {
private $eventEmitter;
public function __construct() {
$this->eventEmitter = new EventEmitter();
}
function addBid($bidderName, $bidAmount) {
$this->eventEmitter->triggerEvent('bid', [$bidderName, $bidAmount]);
}
function addEventListener($eventName, callable $listener) {
$this->eventEmitter->addEventListener($eventName, $listener);
}
function removeEventListener($eventName, callable $listener) {
$this->eventEmitter->removeEventListener($eventName, $listener);
}
function removeAllEventListeners($eventName) {
$this->eventEmitter->removeAllEventListeners($eventName);
}
}
Here's how #3 (traits) would look like:
trait EventEmitterTrait {
private $eventListenersByName = [];
function addEventListener($eventName, callable $listener) {
$this->eventListenersByName[$eventName][] = $listener;
}
function removeEventListener($eventName, callable $listener) {
$this->eventListenersByName[$eventName] = array_filter($this->eventListenersByName[$eventName], function($existingListener) use ($listener) {
return $existingListener === $listener;
});
}
function removeAllEventListeners($eventName) {
$this->eventListenersByName[$eventName] = [];
}
protected function triggerEvent($eventName, array $eventArgs) {
foreach ($this->eventListenersByName[$eventName] as $listener) {
call_user_func_array($listener, $eventArgs);
}
}
}
class Auction implements Observable {
use EventEmitterTrait;
function addBid($bidderName, $bidAmount) {
$this->triggerEvent('bid', [$bidderName, $bidAmount]);
}
}
Note that the code inside the EventEmitterTrait is exactly the same as what's inside the EventEmitter class except the trait declares the triggerEvent() method as protected. So, the only difference you need to look at is the implementation of the Auction class.
And the difference is large. When using composition, we get a great solution, allowing us to reuse our EventEmitter by as many classes as we like. But, the main drawback is the we have a lot of boilerplate code that we need to write and maintain because for each method defined in the Observable interface, we need to implement it and write boring boilerplate code that just forwards the arguments onto the corresponding method in our composed the EventEmitter object. Using the trait in this example lets us avoid that, helping us reduce boilerplate code and improve maintainability.
However, there may be times where you don't want your Auction class to implement the full Observable interface - maybe you only want to expose 1 or 2 methods, or maybe even none at all so that you can define your own method signatures. In such a case, you might still prefer the composition method.
But, the trait is very compelling in most scenarios, especially if the interface has lots of methods, which causes you to write lots of boilerplate.
* You could actually kinda do both - define the EventEmitter class in case you ever want to use it compositionally, and define the EventEmitterTrait trait too, using the EventEmitter class implementation inside the trait :)
The main difference is that, with interfaces, you must define the actual implementation of each method within each class that implements said interface, so you can have many classes implement the same interface but with different behavior, while traits are just chunks of code injected in a class; another important difference is that trait methods can only be class-methods or static-methods, unlike interface methods which can also (and usually are) be instance methods.
The trait is same as a class we can use for multiple inheritance purposes and also code reusability.
We can use trait inside the class and also we can use multiple traits in the same class with 'use keyword'.
The interface is using for code reusability same as a trait
the interface is extend multiple interfaces so we can solve the multiple inheritance problems but when we implement the interface then we should create all the methods inside the class.
For more info click below link:
http://php.net/manual/en/language.oop5.traits.php
http://php.net/manual/en/language.oop5.interfaces.php
An interface is a contract that says “this object is able to do this thing”, whereas a trait is giving the object the ability to do the thing.
A trait is essentially a way to “copy and paste” code between classes.
Try reading this article, What are PHP traits?

How to acess multiple classes through one parent class in PHP

Lets say I have a class called PageBuilder which I instantiate, send parameters to and call functions from through my index file (which acts as a front controller). There are three sub classes associated with the PageBuilder class: Head, Body and Foot, that are accessed by PageBuilder which basically abstracts them for index.
So in theory you could instantiate PageBuilder and have full access to the other classes as if they were part of PageBuilder.
How can I implement a design like this in PHP5 using any combination of classes, abstract classes and interfaces?
I don't think the above is possible with PHP5, not necessarily because PHP has its limitations but maybe because I am going about the design of my application the wrong way.
Common examples of OOP in PHP don't suffice to help me understand how to structure a more complex design.
Thanks.
Some of the other answers are on the right track. The problem you're running into is that your PageBuilder class is doing too much. Just the name sounds wrong for what you're trying to do with it. A PageBuilder sounds like something that would assemble a bunch of parts together into a Page. Let's call these parts Section. Then, what you want to do is use composition, as several of the answers have hinted at.
Inheritance is often described as an is-a relationship, as in if your Section classes extend the PageBuilder class, then a Section is a PageBuilder. What you want though is a has-a relation ship, as in your PageBuilder class has a (or many) Section(s). Any time you need a has-a relationship, you should be looking toward composition rather than inheritance.
So here might be your class hierarchy:
abstract class PageBuilder
{
//#var Section
public $header;
//#var Section
public $body;
//#var Section
public $footer;
public function render()
{
echo $this->header.$this->body.$this->footer;
}
}
class Section
{
protected $content;
}
class LoginPage
extends PageBuilder
{
public function __construct()
{
$this->header=new Section(...);
$this->footer=new Section(...);
$this->body=new Section(...);
}
}
At this point, you're really kind of re-inventing the wheel by making a crappy MVC system. If this is for a project (rather than for learning), you should consider using one of the MVC frameworks for PHP. (I recommend Kohana, but there are several questions regarding the best PHP versions on Stack Overflow.) If you're thinking of these kinds of things, MVC probably won't be a great leap for you.
From what I understand here you could use the composite pattern
http://en.wikipedia.org/wiki/Composite_pattern
Your controller index has only access to an object that implements an interface IPageBuilder (or a name similar), with some standards function like "generatePage". This object would in reality be some kind of container that contain other object of type IPageBuilder. Those leafs object would be able to build some subsection of the page, like Head, Body and Foot. Each of those leaf object would be of a different class, but they will implement the IPageBuilder interface. When your index object call "generatePage", the container will call in order the "generatePage" method of each of its leaf objects, that will in turn take care of rendering the HTML.
Using this approach, if your Body class become too big, you can always turn it into a container that implements the IPageBuilder interface, for example a blog post Body could consist of an Article object and a CommentList object. The body object would then only propagate the "generatePage" method to its children object.
To create your IPageBuilder object, you can use a factory patterns
http://en.wikipedia.org/wiki/Factory_method_pattern
In all honesty, I have tried those kind of approach in the past to generate my HTML and found them to be kind of overkill. My suggestion would be to use a templating engine instead, like Smarty. Your designer will love you (or hate you less) if do that ^^.
http://www.smarty.net/
If you want to know how to use interfaces in PHP, not that it's very hard...
http://ca.php.net/manual/en/language.oop5.interfaces.php
So if I understand correctly you want Head, Body, and Foot to automatically construct as children of PageBuilder?
There are a couple of ways you could maybe do this.
1) Create variables inside of PageBuilder to hold the classes and use a __call method
class PageBuilder{
private _head;
private _body;
private _foot;
function __construct(){
$this->_head = new Head();
$this->_foot = new Foot();
$this->_body = new Body();
}
function __call($name, $args){
if(method_exists($this->_head, $name)) call_user_func_array(array($this->head, $name), $args);
// Repeat for other classes.
}
}
The problem here obviously being if two classes share the same method then the first one to come up wins. You could probably modify it to pick a class based on the function name pretty easily.
2) Chain everything down.
Abstract class Page{
}
class Head extends Page{
}
class Body extends Head{
}
class Foot extends Body{
}
class PageBuilder extends Foot{
}
Either way its somewhat hacked, you just kind of have to make it work.
PHP only allows you to extend one parent class (which can in turn extend another parent class, etc.). There are no interfaces, meaning you can't inherit functions or properties from multiple interfaces as you could in C++.
As such, you will probably need to do something more like this:
class PageBuilder {
protected Head, Body, Foot;
public function __construct($request) {
$view = $this->getView($request);
$this->Head = new PageSection('head.tpl');
$this->Body = new PageSection($view);
$this->Foot = new PageSection('foot.tpl');
}
private function getView($request) {
// #todo return the template filename/path based upon the request URL
}
}
class PageSection {
private $template;
public function __construct($template) {
$this->template = $template;
}
public function render() {
// #todo process and output the $this->template file
}
}

Categories