Organizing/extending classes in a PHP project - php

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

Related

Organizing classes and properties in PHP - the right way?

Please help me. I need a better understanding PHP OOP principles.
If I have a class property which is immutable for all of the class instances it should be defined as static?
If so, is there a way to be sure that static properties are defined in all classes of that type? As I read in PHP manual, static properties cannot be controller neither by the interface nor by abstract classes? Or am I wrong?
Simple example.
<?php
// Parent class
abstract class Employee
{
abstract public function getAlias();
}
// Child classes
class Manager extends Employee
{
public function getAlias()
{
return 'manager';
}
}
class Security extends Employee
{
public function getAlias()
{
return 'security';
}
}
Tell me, where an alias property should be placed?
I have to be sure that any Employee descendants that will be created in future will have that property defined. Is it OK to keep that kind of properties in dynamic methods? Or they should be placed in constants, static methods or static properties?
Actually the current version is quite ok (if considered with no context) because it makes for a cleaner code, since it closer matches principle of least astonishment. Technically, you could rewrite it as this (but that would actually make it worse code):
abstract class Employee {
public function getAlias() {
return $this->alias;
}
}
class Manager extends Employee {
protected $alias = 'mngr';
}
$user = new Manager;
echo $user->getAlias();
Live code: https://3v4l.org/sjVOT
The more important aspect is the purpose of this code. You mentioned, that you would want to use something like this for dealing with single-table inheritance, but here is the important part:
Your domain entities should not be aware of how your persistence layer works.
And pulling structural information from the domain layer for use in some query-builder is a terrible idea. I would recommend for you to instead looks at data mapper pattern (you probably should actually read the PoEAA book).
Your domain entities should not know any details about how (or even "if") they is being saved or restored.

Traits and classes: worried about length of class

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();
// ...
}
}

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.

Kohana 3 module structure question

everybody! I have a new question about Kohana 3, or rather about a module structure. I develop a small module called Textblock. It's about an ordinary page or a small insertion to the site layout (e.g. a greeting or a slogan, company name). It contains both controllers and models. Models inherit Sprig_MPTT. And one feature I'd like to implement is one could be able to call this module like this:
$textblock = Textblock::get_single(1); //by id
$children = Textblock::get_children_of(4); //id of parent
and not
$textblock = Sprig::factory('Textblock')->get_single(1);
$children = Sprig::factory('Textblock')->get_children_of(4);
Those methods are defined in Model_Textblock class as static.
So, I made a wrapper class Textblock, that inherits Model_Textblock. What if I suddenly want change Sprig to Jelly, for example? Foreground won't change at all. Another advantage, imho, is more clarity for anyone, who wants to use this module (e.g. it could be another programmer in the team).
But there's a doubt if I'm on a wrong way... So, the question itself: is the suggested a right way to organize my module? Or it's preferable to keep ordinary Sprig::factory('Textblock') where Textblock's functionality is needed, remove additional wrapper class and remove static?
There is no need to extend Model_Textblock. You can create a model instance and call its method:
class Textblock {
public static function get_single($id)
{
return Sprig::factory('textblock')->get_single($id);
}
// etc
}
But this way you should copy model methods in your static class (not DRY). Also, what if you have more than one model? All you want (as I understand) is to easily change AR driver. So I'd preffer this kind of class:
class Textblock {
// saved objects, dont create on model twice
protected static $_instances = array();
public static function model($name)
{
if (! isset(self::$_instances[$name]))
{
$model = Sprig_MPTT::factory($name);
// you can add try..catch to prevent exceptions
// or add another checks
self::$_instances[$name] = $model;
}
return clone self::$_instances[$name];
}
}
and use it like Textblock::model('textblock')->get_single($id).

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