Keith Donegan Keith Donegan - 3 months ago 5
PHP Question

Review some code?

Had a bit of spare time to learn some OOP in PHP this evening and hit a brick wall. I am creating a little book library app to keep track of my book collection and thought I would use OOP for practice.

I have a main php file called library.php that contains 2 main classes so far.

  1. class database (connects to mysql, database etc)

  2. class books (contains, title, author, genre info etc and methods to insert data into the db)

So, my questions:

Is it OK to use one file for all of my classes?

And the below code is the process page that will add the books to the db, Is this ok or am I going in the wrong direction?

Also, how do I go about knowing when to create new methods in a class or create an entire new class?

include 'library.php';

// Connect to Host & DB
$database = new database();
$database->mysqlConnect('localhost', 'root', '');

// Retrieve Values
$book = new books();



In my opinion it's better to create a file for every class, where the file is named after the class. I use a slightly different notation than chad birch, namely a Classname.class.php. class autoloading is a nice feature, but I don't use it very often (only under certain circumstances, like MVC, where classes of the same type are added or removed often).

Regarding object modelling: start creating classes for nouns. identify the actors in your application. a method of doing this is to write down what your application is supposed to do, then scan it for nouns and modelling your classes after those. Because a class represents a single object, class names are singular most of the time. If there are multiple objects, you should name it ObjectCollection or something like this (e.g. "BookCollection").

Lets try it:

I want to create a little book library app to keep track of my book collection. It should track the books I own, the genre, the author(s) and the friends I lent them to. Additionally, for every friend the phone number should be stored, so I can call him. All the information is stored in a database.

  1. Book: represents a book ("The godfather", "Cryptonomicon")
  2. Library: represents a collection of Books
  3. Collection: already covered by Library
  4. Genre ("Sci-fi", "Thriller", ...)
  5. Author ("Neal Stephenson", "Mario Puzo")
  6. Friend ("Joe", "Jill", "Jack")
  7. PhoneNumber (an property of a friend)
  8. Database (duh)

Then you build the hierarchy. Which objects contain other objects, how does the relation between them look like?

  • Library contains 0, 1 or more Books
  • A Book belongs to exactly one Genre
  • A Book is written by 1 or more Authors
  • I can lend a Book to 0 or 1 Friend and only to one Friend at a time
  • A Friend has a PhoneNumber

(this will also tell you a thing or two about how your database should look like).

Not everything is obvious. do you really need a phone number class? It's only a string. In this case, you should make it a property. Additionally phone numbers are not really shared between Friend objects (it would make sense if several friends living together having the same number and it often changes, but for now that would be a bit overkill). If the noun can be represent by a scalar value (a string, integer, float) and there are no other values connected to them, it may be overkill to make classes.

So, over time you extend your application. You decided to store not only the phone number, but also the address. Address and phone number are quite similar types of information, so you add other variables for street, city, post code and so on. At a certain point you'll get frustrated because the Friend class grew huge, with lots of properties, getters- and setters-methods, some of whom are prefixed to group them together (Friend->addressStreet, Friend>addressPostCode and so on). So you might decide to relocate those to an own class, called Address (if you leave the phone number to Friend) or Contact, just to keep the code clean (nothing wrong with that, but be careful).

What about class hierarchy and object hierarchy? Don't confuse them, they are entirely different things! A class hierarchy arises if similar classes share some properties but are different in others. So you create one class with the properties and methods they share and child classes which inherit the properties and methods of the parent and also add their own to handle the differences.

In our library example, what could that be? To be honest, I can't think of anything besides one thing that's a bit nonsensical, but let's go for it ... Friends and Authors are both Persons! both have names, phone numbers and an address. But they also differ, because authors write books and friends don't (and authors normally don't borrow your books). So you might define the Name and Address-object in the Person class, but getUnreturnedBooks() clearly belongs to Friend while getBooksWritten() belongs to Author.

It doesn't really make sense because you're never going to process Authors and Friends in the same run. but lets say you needed a list of all the adresses stored in your library, you could loop over your collection of Persons and call getAddress(). To be honest, even PHP is a bad example for this, because you can store whatever types you want together in an array and access them in every way you want, but in strongly typed languages that's not possible. In Java you have to define a datatype for an array, and it's possible to store different types if they have a common inheritance (but you're restricted to the methods the original class had). Enough of that class inheritance voodoo.

An object hierarchy simply states which objects should contain other objects. A library contains book objects. A book contains an author object.

Some additional pointers:

  • try to be descriptive. Don't use names like Library->retrieveValues(), name it Library->getBooks() instead, because Book objects is what you get.

  • sometimes it's a good idea to name methods after the data type they're going to return. It's common if they return booleans. Good naming conventions may be has or is as in Friend->hasBook($book) or Book->isInLibraryCurrently().

  • values that are always the same for all objects of a certain class may be class constants. Lets say, if a Person can be male or female and you're storing that as "m" or "f" in the database, it makes sense define the class constants Person::GENDER_MALE = 'm' and Person::GENDER_FEMALE = 'f', so you don't have "m"s and "f"s scattered in your SQL-queries all over the place.

  • Classes that only generate a single instance could be modelled as Singletons. A good example for this may be the Database class - it's highly unlikely you ever need to open more than one transaction at once. Read more about singletons at Wikipedia (, but it may be a bit early for that.

Update: some people think Singletons are a bad idea, because they're more or less "carved in stone" once you implement them this way. So if you model your Database class as a singleton, but later decide you need more than one database connection (unlikely, but possible), you have a problem. if you take the risk, singletons may be convenient.