PHP Programming/Classes
Basics
[edit | edit source]A class is a structure composed by three kinds of items called members, that is:
- constants;
- variables called "properties";
- functions called "methods".
Each of which is declared with a visibility that is either explicit (from "private", "protected" and "public") or implicit (that is, omission of a declaration, only allowed for methods for which the default value is "public").
An object is an instance of a class, in which its class's methods (if any) can be called, and its class's members (if any) can be provided with new values overriding the default ones.
Classes
[edit | edit source]A simple class can be defined as follows:
<?php
/* Start the class */
class Html {
/*
Declare a public member named "br" with a default value of "<br />" (the
XHTML line break)
*/
public $br = '<br />';
/*
Declare a public (by default) method named "printLn" requiring an argument
named "message"
*/
function printLn ($message) {
/*
Echo the "message" argument followed by the value of the "br" member (accessed
through the use of the "$this" keyword (that represents the current object),
the "->" operator (used to access members) and the member's name ''without''
the "$" character.
*/
echo $message . $this->br;
}
}
?>
However, just because you've created a class doesn't mean you get to use anything in it. A class is an abstract entity. It is a way of saying "here is how to create Html-type objects, and what they do." Before you can do anything with the members of a class, you must make an instance of that class.
That is, you must actually make an "Html" object and work with that.
Objects
[edit | edit source]Once you have defined a class, you will want to try it out. Objects are instances of a class. Using objects in PHP is as follows
<?php
$myPage = new Html; // Creates an instance of the Html class
$myPage->printLn('This is some text'); // Prints "This is some text<br />"
?>
The new concepts in that piece are:
- The
new
keyword — Used to make a new instance of an object, in this case an object of the classHtml
. - The
->
operator — Used to access a member or method of an instantiated object, in this case, the methodprintLn()
Now, the fact that the representation of a line break is defined within a member of the class allows you to change it. Note that the changes will only concern an instance, not the whole class. Here is an example (note that "<br>" is an HTML line break and "<br />" is an XHTML line break):
<?php
$myPage = new Html; // Creates an instance of the Html class
$myOldHtmlPage = new Html; // Creates another instance of the Html class
$myOldHtmlPage->br = "<br>"; // Changes the value of the "br" member of the "$myOldHtmlPage" instance to the old HTML value
$myOldHtmlPage->printLn('This is some text'); // Prints "This is some text<br>", the new value of the member is used
$myPage->printLn('This is some text'); // Prints "This is some text<br />", the default value of the member is kept
?>
However, note that it is better to avoid modifying an instance's members: to allow the instance for possible constraint validation, one should instead add to the class (and use while dealing with instances) "get_br" and "set_br" methods to get and set the value of the member while allowing the instance to perform tests and possibly reject the change.
Scope
[edit | edit source]The scope of an item of a class defines who is allowed either to call it (for methods) or to read / change its value (for properties).
Scope definition is compulsory for properties and facultative for methods where "public" is the default value if nothing is specified.
Public
[edit | edit source]Public items can be accessed anywhere.
Protected
[edit | edit source]Protected items defined in a class are accessible to the object that instantiates this class or a subclass of this class.
Private
[edit | edit source]Private items defined in a class are accessible to the object that instantiates the class.
Members
[edit | edit source]Constants
[edit | edit source]They are declared with const
(instead of define()
in procedural programming) and can optionally been followed by a default value:
const MY_CONSTANT_1 = 0;
They can be retrieved by reflexion with:
$myClass1::getConstants();
Properties
[edit | edit source]Even though declaring class properties as public makes their use easier, it is generally not recommended. Should you decide in future versions of the class to perform any kind of check on a public property, or store it in another additional property for caching purposes, you couldn't, since the rest of the code would still use the public property without any check.
Therefore, one should prefer (except in special cases) not allowing public access to properties, and provide simple "get_foo" and "set_foo" methods to return or overwrite them, leaving open the possibility of adding complexity if required.
They can be retrieved by reflexion with:
$myClass1::getProperties();
Methods
[edit | edit source]Since the methods provide the actual interface between an object and the rest of the world, it makes sense for almost all of your methods to be in public access.
More precisely, any method intended to be called from the outside should be public. However, methods only meant for internal use and that aren't part of the interface should not be public. A typical example being an object abstracting a connection with a database while providing a cache system. Different public methods should exist to allow interaction with the outside world, but, for example, a method sending a raw SQL request to the database should not be public, as any foreign code calling it would bypass the cache and potentially cause useless load or (worse) loss of data as the database's data may be outdated (if the latent changes have taken place in the cache).
They can be retrieved by reflexion with:
$myClass1::getMethods();
Practical use
[edit | edit source]The above example doesn't make the case for classes and objects. Why go to the bother of creating all that extra structure just to access functions?
Let's give an example that can show how this sort of thing would be useful:
<?php
class Html {
private $source = "";
public function printLn ($message) {
echo $this->source .= $message . "<br />";
}
public function show () {
echo $this->source;
}
}
$elvis = new Html();
$goth = new Html();
$elvis->printLn("Welcome to my Elvis Fan Page! Uh-huh, uh-huh, uh-huh.");
$goth->printLn("Entree the Goth Poetry Labyrinth of Spoooky Doooommmm...");
$elvis->show();
?>
Some things to note:
- The statement echo $this->source .= $message ."<br />"; first changes the value of the private property $source and then prints the changed value. The changed value is saved.
- A different copy of the $source property exists within each instance of the Html class.
- The printLn and show functions refer to the same copy of $source that was called for their object. (When I call $elvis's printLn function, it changes $elvis's $source variable and the statement $elvis->show(); prints the changed value of $source).
- Using standard variables and methods, there would be a greater risk of sending the wrong content to the wrong page. Which could be horribly confusing for my website visitors.
Now we can start to see how we could save some time and trouble using classes and objects. We can now easily manage two potential web pages at once, printing the correct content to each. When done, we can merely call a page's show function to send that page's html source to the output stream.
I could add more features to all of the objects just by adding variables and functions to the governing class, and I could add more objects at will just by declaring them. In fact, the more complicated my program gets, the easier everything is to manage using object-oriented programming.