The Backwards PHP 5.3+ Guide
For PHP beginners and OOP/MVC beginners
A tutorial by Kyek, started October 8, 2010
A quick introduction
Every PHP guide I've seen on the internet or in books teaches PHP in the wrong direction. They tell you the commands, the functions, the loops, the arrays, and only at the very very end do they teach you how to use classes and objects, and almost none of them touch patterns like MVC. So by the time you get to that point, you're already so used to writing awful code that organizing it in logical pieces just seems like a hassle. Impossible, even, if you've already gotten into a project by that point. This guide puts an end to that, and teaches PHP backwards -- the right way. You'll learn classes and object first, then the commands, functions, loops, and arrays to put inside of them -- using the MVC pattern the whole time. If this sounds like a whole lot of gibberish, keep reading ;-)
Chapter 0: Before You Begin
Know What PHP Is!
A lot of people think they need to learn PHP without actually knowing what it is. So here goes: PHP is a scripting language that webservers run to produce a webpage before sending that webpage to your users' web browsers. PHP is *not* code that executes inside of people's web browsers -- to do that, you need Javascript. PHP can only be read and run by your server itself, and the browser simply shows you the result. A simple example of this is that PHP allows you to print the current date out on a webpage. Then, if you right-click the page in your browser and hit "View Source", you'll see the date right in there, as though you typed it directly into the HTML file and uploaded it yourself.
Know If You're Ready To Learn It
PHP is a great language and very easy for programming beginners to pick up. But before you can use it effectively for websites, you need to have a good understanding of HTML and CSS -- and it really doesn't hurt to have decent knowledge of Javascript, either. If you're weak with your HTML code, though, you'll want to bone up on that before continuing.
Setting Up Your Environment
Before beginning this guide, you need to have a PHP development environment set up on your own personal computer. Some folder where you can put PHP files, load up a URL that starts with http://localhost in your browser, and see the result of your code. Later, you'll also need a MySQL server running on your computer, preferably with a copy of PHPMyAdmin preinstalled. If you're on Windows, the fastest and easiest way to get up and running is by downloading a free copy of WAMP. Mac users can use MAMP. Setting up your environment some other way? Just make sure your version of PHP is 5.3 or higher!
Chapter 1: Hello, World! (or, intro to classes and functions)
Writing the PHP
If you're a veteran programmer, you know that writing an application that prints "Hello, World!" is generally the first program you write when learning a new language. If you're not a veteran programmer, I have a fun fact to share with you! Writing an application that prints "Hello, World!" is generally the first program you write when learning a new language!
To do this, we're going to use two PHP files. Seems like overkill for printing one whole line of text, I know-- but there's method to the madness! So find the root folder of your development environment -- the "webroot" -- and we'll start from there. If you're using WAMP or MAMP, consult the documentation if you can't find what folder that is. Within the webroot, create the path 'lib/mysite/controllers' to drop HelloController.php into, and put index.php in the webroot itself.
lib/mysite/controllers/HelloController.php
<?php
namespace mysite\controllers;
class HelloController {
public function sayHello() {
echo "Hello, World!";
}
}
?>
index.php
<?php require_once(__DIR__ . "/lib/mysite/controllers/HelloController.php"); use mysite\controllers\HelloController; $site = new HelloController(); $site->sayHello(); ?>
Load up index.php in your browser, and ta-da! It says "Hello, World!"
Understanding the PHP
I'll be honest: If this were any other PHP book, it would have told you to make one PHP file with the line
<?php echo "Hello, World!"; ?>in it and call it a day. But writing a site like that is bad form. The reason why that's bad form, as well as many of the technical things that make this more advanced code, are all things you'll learn slowly over the course of this guide. For now, let's go through this code to get just a basic understanding of what each line does, and we'll revisit any interesting pieces later.
lib/mysite/controllers/HelloController.php
Most good webapps are designed with what's called an "MVC", or "Model, View, Controller" pattern. MVC is a guideline for how to separate different kinds of functionality so that your code stays clean and easy to maintain. We'll work more with this as we go, but for now, know that the "Controller" part of MVC is the part that has the "Business Logic" -- a fancy way of saying that the Controller is what loads a page, knowing all the work that needs to be done to get to that point. For now, we're starting nice and easy. So let's get into the file itself!
<?php
In order to tell your server what's PHP code and what's not, we use <?php ?> tags. Anything inside of those tags will tell the server "I'm code! Run me!", while anything outside will be sent to the web browser like any other text or HTML. Soon, we'll try mixing HTML and PHP together using this concept; for now, though, all of our PHP files will start with <?php and end with ?>. Now you understand the first and last lines of HelloController.php ;-)
So let's hit the real first line, now:
namespace mysite\controllers;
This tells PHP that everything in this file will belong to the "mysite\controllers" namespace. Namespaces are simple -- they're just a way to make sure that the names of classes, functions, and variables in your code don't get inadvertently changed or overwritten by someone else's code that uses similar names. As long as your namespace is unique, you're safe. Namespaces can be anything, but they're most useful when you make the namespace the same as the path to the file. So, ignoring the 'lib' folder because we want our namespace to start with the app name, HelloController is in mysite/controllers. We flip the forward-slash to a backslash (the official separator for namespaces), and we have it
class HelloController {Almost all the code in your webapp will exist inside of a "class", or a big group of code all meant to perform a similar task. That opening-brace (the '{') means that any code after it and before the closing brace ('}') will belong to the HelloController class. The name of that class is arbitrary -- we could call it "class Sharkbait_HuHaHa" and it would still work just fine.
public function sayHello() {
echo "Hello, World!";
}Functions are blocks of code that you can call over and over and over again. This particular function is named "sayHello", because all it does is print out "Hello, World!" to the browser. You might have already assumed that the 'echo' command just prints out text-- and if you did, then you're learning pretty quickly
index.php
<?php
Again here, the file starts with <?php and ends with ?> to let the webserver know that everything in the file is PHP code. With that, let's move on:
require_once(__DIR__ . "/lib/mysite/controllers/HelloController.php");
It would be cool if PHP could magically "find" all the class files that we want to use, but unfortunately it's not that smart quite yet. Until then, we can use a built-in function called require_once to load any PHP files that we might need to use. Since index.php is the file that we're actually loading with the browser, we use require_once to load in the contents of any other PHP file we'll need to show the page. All we have to give it is the path. We start with __DIR__, which is a keyword that PHP will automatically replace with the absolute path to the current file, index.php. This might be something like "C:\Users\Barney\TheOnlyThingOnMyComputerThatIsntPorn". After that we have a single '.', which, believe it or not, is actually a command in PHP. It's called a 'concatenator', and any two "strings" or lines of text that it falls between, it will join together. So we join together your current path with the path from here to the file we want, and ta-da, require_once has everything it needs!
use mysite\controllers\HelloController;
Remember how namespaces keep your code from conflicting with other similarly-named code you might be using? Here's why. For any class you've loaded in with require_once and now want access to use, you just tell PHP to 'use' it. You specify the class by typing its namespace, followed by the class name itself. Now, any time we use HelloController in our code, it will know that what we really want to use is mysite/controllers/HelloController
$site = new HelloController();
Classes are like blueprints. They have all the data you need to make something useful, but you need to build the object before you can start using it. So to make an object from our class, we need a few different things:
$sitein PHP, anything starting with $ is called a variable. A variable can contain numbers, text, or even Objects, a usable version of our blueprint class. All we do now that we have a variable is create a, *cough cough*, new HelloController object. Then we take that new HelloController object, and insert it into our variable, $site. This is pretty hard to understand until you use it, so let's use it!
$site->sayHello();
So we know that $site now has all of the HelloController class's code hiding inside of it, and we know that we need to run the "sayHello" function in order to print "Hello, World!" to the screen. Thankfully, this process is very easy
Feeling Overwhelmed?
That's ok! Because I'll let you in on a little secret: what you just learned is the hardest part of PHP. I warned you that you'd be learning this language backwards ;-). All of our code from here on out will be written in classes and functions, so if you're not quite grasping what they are and why we use them now, just keep on reading and you'll settle into the idea when we use it more. Just feel safe in knowing that it all gets easier from here.
Chapter 2: More Pages! (or, intro to conditionals)
Less is More, but One is Everything.
Good webapps separate the logic for each page into different PHP files. Great webapps split each page into separate files, but load them all through index.php! Sound crazy? Let's do it, then you'll see how easy your life becomes.
A Controller with a View
We've gone over what the Controller is in the Model View Controller structure -- now, let's talk about the View. In our Hello World example above, we're simply echoing out some text. But for most pages, we're going to need a lot more than that! You don't want to echo out things like "<html>" and "<title>My Site</title>" because not only is that a lot of PHP code, it would get incredibly messy. The best thing to do is write a plain old html file, but add bits of PHP code to output any variables you need to display.
Telling Controllers Where to Find Views
If the controller is going to be responsible for loading these HTML pages, it has to know where to find them! So let's add a line to the very top of our index.php:
index.php
<?php
define("VIEW_PATH", __DIR__ . "/views");
require_once(__DIR__ . "/lib/mysite/controllers/HelloController.php");
use mysite\controllers\HelloController;
$site = new HelloController();
$site->sayHello();
?>
define() is another built-in PHP function. You use it to make a very specific kind of variable called a "Global Constant". Global constants are available from any file or class within your application, and can never ever be changed while the PHP script is executing. In this new line, we're making a new global constant called "VIEW_PATH", and using the same __DIR__ and concatenator syntax that we used in the require_once call to define a path to a "views" folder off of the webroot. Now, any controller that needs to load a view has a way to find the view files!
The Calculator Page
So, knowing about Views, we're going to create three files to make a page that can add two numbers together: A Controller, a View for the calculator form, and a View for the calculator results page. Here are the files -- and remember, these paths should come from the webroot!
views/calc_index.php
<!DOCTYPE html> <html> <head> <title>My Site : Calculator</title> <head> <body> <form method="get" action="index.php/calc/results"> <input type="text" name="num1" /> <input type="text" name="num2" /> <input type="submit" value="Add!" /> </form> </body> </html>
views/calc_results.php
<!DOCTYPE html> <html> <head> <title>My Site : Calculator Results</title> <head> <body> The answer is <?php echo $answer; ?>! </body> </html>
lib/mysite/controller/CalcController.php
<?php
namespace mysite\controllers;
class CalcController {
public function index() {
require(VIEW_PATH . "/calc_index.php");
}
public function results() {
$answer = $_GET['num1'] + $_GET['num2'];
require(VIEW_PATH . "/calc_results.php");
}
}
?>
Picking out your URL scheme
Now we have a Controller that loads the Views and that's awesome -- but before we can actually load this page, we need a dispatcher! A Dispatcher (often called a "Router" as well) is a block of code responsible for looking at the URL you're loading, and passing your request off to the correct Controller. In our case, we'll be looking at the URL and deciding if we should load up HelloController or CalcController. So the first step is figuring out what URLs we're going to use!
We already know that we have to load index.php. So there's a couple options for how to add extra information to a URL without actually changing the file you're loading -- and since this is the backwards PHP guide, I'll start you with the best and most advanced solution: PATH_INFO!
index.php/hello index.php/calc index.php/calc/results (this is your calculator results page)
Believe it or not, adding a slash and then more info after your .php file will still load the PHP file. What's more, the PHP engine will even create a variable for you to read what extra info was included!
Adding your dispatcher to index.php
Here's the index.php with our Dispatcher AND the require_once line to bring in our CalcController. Once this is in, you can load the pages with the URLs I gave above. But keep reading, because this does you no good unless you know how it works ;-)
index.php
<?php
define("VIEW_PATH", __DIR__ . "/views");
require_once(__DIR__ . "/lib/mysite/controllers/HelloController.php");
require_once(__DIR__ . "/lib/mysite/controllers/CalcController.php");
use mysite\controllers\HelloController;
use mysite\controllers\CalcController;
// Request dispatcher
if ($_SERVER['PATH_INFO'] == "/hello") {
$controller = new HelloController();
$controller->sayHello();
}
else if ($_SERVER['PATH_INFO'] == "/calc") {
$controller = new CalcController();
$controller->index();
}
else if ($_SERVER['PATH_INFO'] == "/calc/results") {
$controller = new CalcController();
$controller->results();
}
else {
echo "You must choose a page!";
}
?>
Wow, all kinds of new stuff there! First, two lines I don't need to explain: The extra require_once for CalcController, and the second 'use' line for CalcController with its namespace. Those are just there to load our CalcController class, just like the lines for HelloController. And another thing that's super easy to explain:
// Request dispatcherThis line is called a "comment". Any line that starts with a double-slash "//" is considered a comment, and you can type anything you want there without it affecting your code. It's good practice to drop in comments for any piece of your program that might need more explanation if someone else were to read your code.
But now we're getting into some logic we've never seen: IF statements! An 'if' statement allows you to write some expression that can boil down to "true" or "false". For example, let's say you type:
if (4 > 9000) {
// Do something here...
}You'll never reach the "Do something here" section, because 4 is obviously not over 9000 -- so it's "false". But if I were to type:if (1 == 1) {
// Do something else...
}1 is definitely equal to 1, which is "true", so any code we put inside of those curly braces will run!Let me pause quick to talk about that '==' sign: That looks crazy, right? I mean, in all of our old math classes, we just used one = sign to say if something was equal to something else. In the programming world, though (and this is true for nearly ALL programming languages), the single = sign is to assign a value to a variable. So saying:
if ($myVar = 2)wouldn't actually compare $myVar with 2 to see if they're equal -- it would literally put the value of 2 into the variable $myVar, overwriting whatever $myVar was already holding. That's bad news! So for comparisons, we use double-equals signs. There's also triple-equals signs, but that's more advanced stuff that we don't need quite yet
if ($myVar == 2)will see if the variable $myVar ALREADY contains the value 2, and if not, will return "false" so that the code inside of that if-statement doesn't run.
[[ To Be Continued! ]]






Cartoon Clouds
Mountains
Sunrise
Clouds
Green Clouds
None










sign under their reply :)















Help