Jump to content

Database and PHP Organisation


TeddyKiller

Recommended Posts

I know a standard degree of MySQL and PHP.

My problem is Organisation. I absolutely suck at it.

 

Right so I have a social networking site, you should know what it includes... quite alot of features. Although the basics are..

login system, profiles, friends, mails, comments.

 

Now I have it all working.. the fact is.. my code is ending up like a thunderstorm. It is horrible.

I'm planning out an update. As in.. whole site update.

 

I'm actually wondering.. any tips in organising the site and database.

You may contribute ways you'd organise the database etc, or you may give tips, to make the best out of organising.

 

Sorry if I ain't clear.

Thanks

Link to comment
Share on other sites

If your not sure what I'm talking about then your not. You would need to learn OOP first, then take a good look at learning the common design patterns.

 

There is no quick fix.

 

Maybe you should take a look at one of the many available frameworks?

Link to comment
Share on other sites

It all depends on your host whether you are using a (virtual) dedicated server or shared hosting. Although there are some conventional directory layout's I generally stick to my own:

 

(virtual) dedicated server
--------------------------
private_html
`- modules
    `- www ([b]www[/b].domain.com)
    `- admin ([b]admin[/b].domain.com)
`- settings
    `- www.ini
    `- install.ini
`- libraries
`- templates
    `- scripts
    `- layout.phtml
public_html
`- images
`- scripts
`- styles
`- index.php
`- sitemap.xml

 

For shared hosting I generally use the same above structure but move everything from private_html to public_html and add the necessary .htaccess files.

 

For my database structure I tend to use:

- plurals for database tables

- singulars for all fields including FK

- if the table is specific to a certain part of the system I prefix it for example: forums, forums_topics

 

If you go through Google you'll find some good naming conventions for your database tables, field names, ..

 

@thorpe where did he mention the use of OOP?

 

The OOP principles (the more popular one's) thorpe is referring to are:

- program to an interface, not an implementation

- favor object composition over object inheritance

 

SOLID:

Sinlge Responsibility Principle (SRP): Every class should have only one responsibility for example User, Zend_Auth all serve just one purpose

 

Interface Segregation Principle (ISP): this means that you should make your interfaces cohesive, group by functionality, for example you can instantly see that something here is wrong:

 

interface AuthInterface {
  public function login();
  public function isAuth();
  public function getProducts();
}

 

getProducts() is here clearly not the responsibility of AuthInterface and any class implementing this interface has the unnecessary overhead of getProducts()

 

Open-Closed Principle (OCP): open for extension but closed for modification, in practice this applies to interface's (see ISP) but can also apply to classes that you have used in previous projects (do not mess in their source, extend them)

 

Liskov's Substitution Principle (LSP):

 

MyClass mc = new MyClass();

 

should be:

 

MyParentClass mc = new MyClass();

 

the use new MyClass(); is also bad as in whichever class you did use this you made it tightly coupled and a factory would be better:

 

MyParentClass mc = MyParentClassFactory.factory(..);//basically you now can use any child of MyParentClass

 

try to go as high as possible (interface) but make sure that all required functionality is covered, the following example is wrong:

 

interface MyInterface {
  public function doSomething();
}

abstract class MyAbstract {
  public function doSomethingElse();
}

MyInterface mi = SomeFactory.getClass();
mi.doSomethingElse();//guarantee that your code will break at some point

 

Dependency-Inversion Principle (DIP): stirred up some serious discussion a while back. This means that you should pass collaborators (class members) as parameters

 

public function __construct() {
  $this->object = new Object();
}

 

public function __construct(ParentObject $o) {
  $this->object = $o;
}

Link to comment
Share on other sites

Thanks for that ignace. Really appreciate it! Unfortunately, i'm rather lost with 'interfaces'

I do understand your little example where getProducts() shouldn't belong in there.

However.. how would you access interfaces. Would it be similar to classes..

blah = new myinterface();

Then you can access any function within that interface?

 

Also,

MyParentClass mc = MyParentClassFactory.factory(..);//basically you now can use any child of MyParentClass

Whats the use of 'mc'.. and what is the difference between 'new myclassname();' and 'MyParentClassFactory.factory' apart from the name that is. Do they both do the same thing? I'm confused.

 

Thank you for taking your time to help me.

Link to comment
Share on other sites

An interface defines behavior but allows implementing classes to define the implementation. The AuthInterface for example defines isAuth() && login() but does not give the implementation so implementing classes can use sessions, flat-files, sql, .. Because of this you can use interface's as "flags" whenever you see one you know that the passed objects contains those defined methods when they don't a fatal error occurs.

 

An interface and an abstract class can not be instantiated only implemented or extended respectively. The difference between an interface and an abstract class is that the latter can define an implementation and let all others to fall-through (for example if one method is the same for all extending classes).

 

what is the difference between 'new myclassname();' and 'MyParentClassFactory.factory'

 

Whenever your wite new SomeClass() you couple it directly to the class which uses it and you will need to go into the source whenever you want some other class to handle it (and if Java re-compile). A factory or a builder allows you to define the implementation at run-time, which means that it can vary (be it SomeClass or SomeOtherClass, even SomeOtherOtherClass). It makes your code flexible. All of these "laws" (software design principles) have one thing in common: to support change (the only true guarantee in software architecture).

 

According to Robert C. Martin [Design Principles & Pattern] a bad design can be identified by 4 factors:

 

Rigidity every change brings along other changes to the system

Fragility every change brakes your system

Immobility you can't port it to another application without having to alter the code

Viscosity easier to go around the problem in your software then to actually solve the problem

Link to comment
Share on other sites

More accurately, an interface declares functionality, leaving the class(es) that implement it to define how that functionality should be handled.  All methods listed in an interface must be defined in a class that implements it.  And, no, you cannot use the 'new' keyword with an interface.

 

Interfaces help enforce type.  If a class implements an interface, then you know that those interface methods will be available.  An object of that class is also considered to be an object of that interface, allowing you to use that fact in type hints.  So, something like:

 

class Book implements IProduct {}

$book = new Book();

 

Means that $book is a Book, and it's also an IProduct.

 

A factory is a method that implements the Factory Method design pattern.  It's a static method that takes information as an argument and returns the correct object based on that information.  What that information is, and what objects it can return, are dependent on what kind of objects you need it to return, and what info is necessary to create such an object.  A classic example is a Database factory:

 

abstract class DatabaseFactory
{
   public static function instance($connectionString)
   {
      // return correct type of db object (MySQL, SQLite, postgreSQL, etc) based on the connection string
   }
}

$db = DatabaseFactory::instance(/* connection string */);

 

What makes this flexible is that you don't actually need to know what kind of database $db is.  You're just certain that it's a db, and that you can execute queries with it.  The particulars are hidden.

Link to comment
Share on other sites

interface IProduct {
  public function getPrice();
}

interface IBook extends IProduct {
  public function getISBN();
}

class Book implements IBook {
  public function getISBN() {
    return $this->isbn;
  }
  
  public function getPrice() {
    return $this->price;
  }
}

class Client {
  public function setBook(IBook $b) {
    echo $b->getISBN(), $b->getPrice();
  }
}

class OtherClient {
  public function setProduct(IProduct $p) {
    echo $p->getPrice();//$p->getISBN() is not possible altough I can pass a Book object
  }
}

Link to comment
Share on other sites

I added in some comments for that ignace. Can you correct me where I'm wrong. (I had a look at the php.net manual of Interfaces)

<?php 
interface IProduct 
{
  public function getPrice();
}

interface IBook extends IProduct 
{
  public function getISBN();
  //This also includes public function getPrice(); as it extends IProduct
}

class Book implements IBook 
{
  public function getISBN() //Function for.. public function getISBN();
  {
    return $this->isbn;
  }
  
  public function getPrice() //Function for.. public function getPrice();
  {
    return $this->price;
  }
}

class Client {
  //This allows both functions as IBook is an extension of IProduct, so IProduct is included in IBook...
  public function setBook(IBook $b) {
    echo $b->getISBN(), $b->getPrice();
  }
}
//To call the class and setBook()
$Client = new Client();
$Client->setBook();

class OtherClient {
  //This doesn't allow getISBN() as that isn't in the interface of IProduct
  public function setProduct(IProduct $p) {
    echo $p->getPrice();//$p->getISBN() is not possible altough I can pass a Book object
  }
}
//To call the class and setProduct()
$OtherClient = new OtherClient();
$OtherClient->setProduct();
?>

Link to comment
Share on other sites

Teddy,

 

I just strarted reading this book: http://www.amazon.com/Object-Oriented-Thought-Process-3rd/dp/0672330164/ref=sr_1_1?ie=UTF8&s=books&qid=1272075133&sr=8-1

 

Its about object oriented design, and it tries to stay away from coding as much as possible, just to explain the theory behind OOP and MVC. I'm still a novice programmer, but I've recently started playing around with different frameworks.  Looking at how everything is organized and implemented is very helpful. 

 

I just got this book today as well: http://www.amazon.com/Practical-Web-2-0-Applications-PHP/dp/1590599063/ref=sr_1_1?ie=UTF8&s=books&qid=1272075358&sr=1-1

 

I haven't read it yet, but it had some good reviews on amazon. It teaches you how to build php web applications. I guess most of the examples are using zend framework.

 

But yeah, I think learning a framework that uses mvc would be the best way to go about it.

Link to comment
Share on other sites

@ignace

 

I almost cried reading your original post--it was beautiful.  :'(

 

What you need to understand about interface vs implementation is that the interface is where you define what functions you will be needing in EVERY implementation.

 

An implementation is the class that inherits the interface.

 

The best way to model all of this is to draw it on paper, just like a file directory.  You put objects at the top of the list and subcategories of those topics.  Take all of your classes and organize them into a "family tree"  Show which classes have overlap, and make an interface for those overlapping. 

 

Lets say you have 3 classes that are database interactions:  user, friends, and comments.

 

So all of these have a table that they relate to, so we can put those functions into a top level interface with functions such as update() and insert().  Lets say that friends and user have functions such as getUser() and printPicture().  You can put these into a different category and have an interface that defines these functions.

 

dataInterface

|----userInterface

        |---user

        |---friend

|----comments

 

 

What OOP is ALL about is inheritance!  Everything that can have family relationships should.  There of course are more advanced topics to OOP but one of the fundamentals is inheritance.

Link to comment
Share on other sites

@ignace

 

I almost cried reading your original post--it was beautiful.  :'(

 

thanks, it's nice to know that what I say is appreciated. If you are interested in exploring this further I can recommend Applying UML and Patterns (Craig Larman), Domain-Driven Design (Eric Evans), Writing Effective Use-Cases (Alistair Cockburn)

 

The best way to model all of this is to draw it on paper, just like a file directory.  You put objects at the top of the list and subcategories of those topics.  Take all of your classes and organize them into a "family tree"  Show which classes have overlap, and make an interface for those overlapping.

 

I want to elaborate on that. Like Andrew said you start out by drawing on paper, to be more precise you draw a domain model. This has no interface's, no abstract classes, just (early) concepts. If you were to model a dice game you would identify Dice, DiceGame, and Player. You would find that 1 Player plays 1 DiceGame, 1 DiceGame includes 2 Dice and 1 Player rolls 2 Dice.

 

You have defined your concepts and their underlying relations. Finding the correct concepts is not always so obvious though, sometimes something that may seem relevant at first may turn out to be completely irrelevant later (as your knowledge of the (problem) domain grows and your model changes).

 

A domain model is a handy tool during meetings while you gain a deeper understanding of the domain. When you explain the new model to your client he will hear when something you say sounds weird and correct you (and your model changes again). This entire process transfers the domain knowledge of your client onto you into the model, once you both agree on a model a prototype (production-quality) can be created and tested by the client to verify the correctness of the model.

 

Important to realize is that domain modeling takes place whenever you are to create a system you know little about. For example when you are to create a e-commerce system with some very specific business rules that deviate from a standard e-commerce system (as most by now realize how one works) although you should be aware that the client can have a different understanding when he says e-commerce.

 

A domain-model is to gain a deeper understanding of the domain before you start out to create your class diagram.

 

It takes a lot more then this post to explain the entire UP (Unified Process) to explain OOA&D (OO Analysis & Design).

Link to comment
Share on other sites

Thank you. I've bookmarked this thread as it completely makes no sense to me, for further reference so that I can understand it.

I think I know the very basics of interfaces etc.. although coding and understanding the code is another topic to me.

 

So.. start off with a domain model, do you have any good.. examples of this.. the image you gave me, looks more like.. an interface. The relevance to other functions?

Link to comment
Share on other sites

You remind me of myself. Once I was also trying to follow a formal path but to be honest you need to follow whatever you are most comfortable with. There are a few rules I follow and I find very useful is:

 

1) Work in iterations, show your work (every 2 weeks for example) to your client so that he can correct any misunderstandings

2) If there is something that is new to you, start with that first and show it to your client to make sure you both are on the same page (high-risk, high-value)

  In an e-commerce this could mean to start out with the checkout process even before anything else has been developed, a sample prototype would do fine.

3) Adhere to software principles (SOLID) during software design

4) Keep It Simple (take the simplest that could possibly work)

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.