PHP, MySQL, JavaScript & HTML5 All-in-One For Dummies (2013)

Book VI: Web Applications

Web Applications

9781118213704 pp0601

Chapter 1: Improving Your PHP Programs

In This Chapter

arrow.png Including helpers automatically

arrow.png Reusing code

In earlier chapters, you’ve seen how to program in PHP. You’ve seen how to create a program, how to loop, set up conditionals, and more. All of that knowledge has enabled you to create PHP programs that work well on the web. But you can make them even better, even easier to use, and that’s what this chapter is all about.

In this chapter you’ll see how to improve and extend your PHP programs and how to create and use helper functions automatically. You’ll also see ways to reuse code rather than reinventing it every time you need it.

Automatically Including Helper Functions

Once your programs reach a certain length and complexity, you find that there are a lot of includes and require_once() functions. Each time you make a new file or try to make something into a common function, you also need to go back through all the programs and add a newrequire_once. That can quickly become monotonous. Luckily, there's a way around it.

Using auto_prepend_file

You can automatically prepend a PHP file so that its code is executed before the actual file being requested. In other words, if you send a visitor to a URL similar to http://www.example.com/login.php, you can use auto_prepend_file to always require a helper file prior to the login.phpcode being run. That helper file could start the session, provide several functions that are used within your programs, or even load other files.

The auto_prepend_file function is part of your php.ini file, but it's more common to set it in the Apache configuration using the php_value directive, like so:

<Directory "/my/documentroot/path">

    php_value auto_prepend_file "/my/documentroot/path/prependfile.php"

</Directory>

The file included with auto_prepend_file is included as if the require() function was used. The practical implication of that means that, if the file being prepended is not found, an error will occur and the program won't continue.

Starting sessions with a prepended file

You learn about sessions in Book IV, Chapter 6. That chapter explains that in order to use sessions, you need to call the session_start() function on every page that will use sessions. This can be cumbersome, especially if you're trying to tack sessions onto several PHP programs. You can use an auto_prepend_file to call session_start and, in doing so, you don't have to change any other files!

In the following exercise, you create two files: one that will be the main file and another containing a prepended function to start a session. Prior to performing this exercise, you should ensure that .htaccess files work or that you can alter your Apache web server configuration.

remember.eps Be sure to restart Apache if you make a change to the configuration.

Within the .htaccess file for your document root, place the following code:

php_value auto_prepend_file "prepend.php"

Alternatively, you can add that line within the <Directory> stanza in the Apache configuration for your web server for your document root. For example, if your document root is "/var/www" you can add that line after the <Directory "/var/www"> directive and before the closing</Directory> line in the Apache config.

tip.eps See www.javascriptkit.com/howto/htaccess.shtml for more information on .htaccess files.

Open your text editor and create a new empty file. Within the file, place the following code:

<?php

if (isset($_SESSION)) {

    print "Session has started!";

} else {

    print "Session has not started";

}

?>

Save the file as session.php within your document root.

Open a web browser and point to http://localhost/session.php. You should see a page like the one in Figure 1-1.

9781118213704-fg060101.eps

Figure 1-1: Viewing session.php in a browser.

Minimize the web browser and create a new file within your text editor. Within that file place the following code:

<?php

session_start();

?>

Save the file as prepend.php in your document root.

Within your web browser, reload the session.php file or go to http://localhost/session.php to view the session.php file you created earlier. You should now see a page like the one in Figure 1-2.

9781118213704-fg060102.eps

Figure 1-2: Verifying that the file has been prepended.

tip.eps If you receive a blank page or an error displayed through the browser, then the prepended file wasn't found. Check the simple stuff, like spelling of the file (prepend.php). Also check to make sure that the file you called with the auto_prepend_file directive is where it should be, in the document root if that's how your web server is configured.

If you receive a page that still says "Session has not started," then there's a chance that Apache isn't seeing your auto_prepend_file directive at all. If you've placed it in an .htaccess file in your document root, you need to make sure that Apache is reading the .htaccess file. Continue reading or check with your hosting provider to see if .htaccess files are allowed.

Some web server configurations don't allow for .htaccess files. You can reconfigure Apache to allow them by changing the AllowOverride directive to All for the directory from which you want to read the .htaccess file (in this case, your document root). The directive should look like this:

AllowOverride All

Prepended files can be incredible helpers, but they also can sometimes cause confusion. For example, if you aren’t sure why a program is doing something, an auto-prepended file can sometimes add to that confusion because it loads so many other files and functions — adding ample room for error. Additionally, every request must now use that auto-prepended file, which can cause performance issues if you chain too many required and included files from that prepended file. With that said, the benefits usually outweigh the drawbacks for prepended files.

Using classes for efficiency

You learn about object oriented programming concepts in Book IV, Chapter 4. One of the items discussed in that chapter is the concept of classes, which define a certain type of object.

Classes can be used to provide shortcuts and helpers throughout programming. For example, you might have a class to define a user. You can then add functions (known as methods) to that user class for common things that users might need to do, like update their passwords.

Without classes, you'd end up having numerous functions laying around in your programs, possibly clashing with each other. Imagine the scenario (this really happened) where you write a set of user management programs without classes. These programs would include functions likechangePassword, addPermission, setEmail, and so on.

Now you want to merge that code with someone else's to add the capability to use groups or roles into your program. Their programs are also written without classes, and they have some of the same function names as your programs, like addPermission. When you attempt to merge them, you'll find no end to the confusion and function name collisions. By the time you get done merging the code, you could've just written it all from scratch again!

On the other hand, if you define your programs using classes, then the addPermission function (method) would never collide with another function because the addPermission method is tied to the user class.

Recall that to create a user in an object oriented manner (called instantiating a user object), you use the New keyword. For example, if your user class was called User (for lack of a less descriptive term), you'd instantiate it like this:

$user = new User;

Then when you call methods, you call them through your own copy of the user object, like this:

$user->addPermission();

Now there can’t be a conflict because a group object would be called something different.

Reusing Code

One of the most important aspects of programming is code reuse. Many programmers have sets of programs or functions that they frequently reuse, at least as a starting point, to speed up their new projects. This section looks at a couple of techniques for code reuse in PHP, though these techniques apply conceptually to JavaScript and other languages, too!

Using functions

Book IV, Chapter 2, touches on code reuse through functions. This section expands on it, in light of your newfound knowledge of auto_prepend_file. You can, with the help of an auto_prepend_file, create a functions file that's automatically included within all your PHP programs. These functions might be something as simple as starting a session or as complex as an entire login function.

tip.eps Whenever you need or think you need to have a function in more than one file, rather than using require_once and include_once, if you're going to use a function in multiple places then you can just as easily place it in an auto_prepend file.

Here’s an example of how you can reuse code through functions. One function that you might use in many places is something to convert a two-letter state abbreviation to its full name. You can create a function to do so and place it in the prepended PHP file.

This exercise assumes that you've completed the preceding exercise to create a prepend.php file and have that file automatically loading through your web server.

1. Open prepend.php from the preceding exercise.

2. Clear any code out of prepend.php and place the following code in the file:

<?php

if (!isset($_SESSION)) {

        session_start();

}

function convertState($state) {

        $stateList = array(

                "AL" => "Alabama",

                "AK" => "Alaska",

                "AZ" => "Arizona",

                "AR" => "Arkansas",

                "CA" => "California",

                "CO" => "Colorado",

                "CT" => "Connecticut",

                "DE" => "Delaware",

                "FL" => "Florida",

                "GA" => "Georgia",

                "HI" => "Hawaii",

                "ID" => "Idaho",

                "IL" => "Illinois",

                "IN" => "Indiana",

                "IA" => "Iowa",

                "KS" => "Kansas",

                "KY" => "Kentucky",

                "LA" => "Louisiana",

                "ME" => "Maine",

                "MD" => "Maryland",

                "MA" => "Massachusetts",

                "MI" => "Michigan",

                "MN" => "Minnesota",

                "MS" => "Mississippi",

                "MO" => "Missouri",

                "MT" => "Montana",

                "NE" => "Nebraska",

                "NV" => "Nevada",

                "NH" => "New Hampshire",

                "NJ" => "New Jersey",

                "NM" => "New Mexico",

                "NY" => "New York",

                "NC" => "North Carolina",

                "ND" => "North Dakota",

                "OH" => "Ohio",

                "OK" => "Oklahoma",

                "OR" => "Oregon",

                "PA" => "Pennsylvania",

                "RI" => "Rhode Island",

                "SC" => "South Carolina",

                "SD" => "South Dakota",

                "TN" => "Tennessee",

                "TX" => "Texas",

                "UT" => "Utah",

                "VT" => "Vermont",

                "VA" => "Virginia",

                "WA" => "Washington",

                "WV" => "West Virginia",

                "WI" => "Wisconsin",

                "WY" => "Wyoming"

        );

        if (array_key_exists($state,$stateList)) {

                return $stateList[$state];

        } else {

                return false;

        }

} //end function convertState   

?>

Save the file (as prepend.php) in your document root.

Create a new file in your text editor and place the following code into the editor:

<?php

$stateAbbrev = "WI";

print "State abbreviation is " . $stateAbbrev . "<br>\n";

$stateFull = convertState($stateAbbrev);

if ($stateFull) {

        print "Full name is " . $stateFull . "<br>\n";

} else {

        print "Full name not found for {$stateAbbrev}<br>\n";

}

?>

Save the file as state.php in your document root. Open a browser and point to http://localhost/state.php. You should see a page like that in Figure 1-3.

9781118213704-fg060103.eps

Figure 1-3: Loading the state.php PHP program.

The code in the prepend.php file first checks to see if the session has been started and starts the session, if necessary. Though it isn't used in this file, it'll be used elsewhere and builds on the example from earlier in the chapter. After that, it's the typical creation of a function, which you see throughout the book. The function, called convertState, accepts an argument of the state to convert. The function sets up an array of the states and their full names. After that, the array_key_exists() PHP function is used to look up the state. If the two-letter abbreviation doesn't exist in the array, false is returned. Otherwise the name of the state is returned.

The state.php file merely called the convertState function, which is automatically "visible" or available because of the auto_prepend_file directive that you already set up. If there's a value in the $stateFull variable, then it's printed; otherwise, if there's no value, as it would be if the value was set to Boolean false (like it might be if no state was found), then a note is printed to that effect.

This example demonstrates a simple but typical function that might be commonly used across a web application built with PHP. By moving this function into a file that’s included everywhere, you can use the function without having to do any extra work, like requiring or including the function’s file, wherever you want the function’s result.

Using object-oriented programming

Another way to promote code reuse is through object-oriented programming (sometimes shortened to OOP). By using an abstract class, which you learn about in Book IV, Chapter 4, you can reuse classes. Object-oriented programming typically also means thinking more about the design of the programming from a higher level, which means that your classes can be built to take advantage of reuse.

An example of higher-level design promoting reuse is where you have multiple classes that need to access user details. Rather than creating separate methods in each of those classes, you can build a superclass or a third class that provides those common methods. Doing so saves from having to create those same methods within each class.