Archive for the 'Schmategories' Category
We’ve already looked at using the GET superglobal array to get data from the user through the URL. Another way to get data from the user is through forms. Different form elements work differently.
Here’s a simple webpage with a form on it, I’ve mixed in one of each of the input element types that HTML provides, not counting ‘file’ since we’ll cover that in a later video:
{show output}
Behind the form, this is what it looks like:
{show source}
The first thing to look at is your form tag. The important attributes here are ‘action’ and ‘method’. If the form only contains a short amount of information – no textareas and text fields with maxchars set at numbers below 255, you can actually send up to 4000 or so characters’ worth of data through the URL when you submit the form. The way this will work is your browser will automatically encode the form data into a string, similar to how http_build_query works, and append it to whatever URL you specify in the action attribute. You do this by specifying GET as the method (that’s not case sensitive).
Personally though, I hate the way GET makes the URL look on any form with more than one or two elements, so I almost always use the other method, called POST. POST transmits the form data in a manner that’s invisible to the user, and it can handle as much data as you need.
To access your user’s submission, you have to specify the address of your php file within the action attribute. If you specify an empty pair of quotes, it’ll just submit the form data to the same URL the form is on.
Some programmers mistakenly assume that POST is somehow more secure than GET, just because the data is in plain sight in the address bar. And it’s true the if you want to prevent a hacker from sending someone to a completed form by using a link, then yes, POST might be better. But the truth is, in most respects, while GET is more visible, any hacker is going to have just as easy a time forging a POST request as they would with GET. There’s a whole chapter later in this tutorial that deals with security, but the first rule of security is never trust data that originates from the user. Doesn’t matter whether it’s GET, POST or any of the others I haven’t introduced yet. If it came from the user, check it and make sure it’s valid before you use it.
There are several types of input elements you can add to a form. You’ve probably encountered them all at some point just as a web surfer. However, we’re only going to look at a few. These are the text box, checkbox, radio button, hidden field, and the submit button.
All of the fields we’re going to look at are variations of the “input” HTML element. The input element has one required attribute – “type” and a few optional attributes. If you don’t specify a type, you’re violating the w3 standard for HTML, but in most browsers, rather than breaking the page, they’ll just treat it as text, since it’s the most common. So since it’s sort of the default, we’ll look at that first.
Here’s a simple text input element:
<input type=”text” name=”text1″>
In addition to a type, if you want to actually collect the data from your form in a meaningful way, another attribute your input elements should have is a name. Whatever type you use it for, the name will become the key your PHP script will use to reference the value submitted.
On the server, there are another couple superglobal arrays we haven’t looked at yet called POST and REQUEST. When I submit this form, the value of this input element, whatever it is, will be contained in the key ‘text1’ in both the POST and REQUEST superglobals. But they’re not redundant. POST will only have variables submitted through a form that uses the post method, whereas REQUEST will contain everything in both POST and GET, as well as another superglobal called COOKIE.
Here, I’ll prove it:
<?php
echo ‘POST[text1] = ‘ . $_POST[‘text1’] . ‘<br>’;
echo ‘REQUEST[text1] = ‘ . $_REQUEST[‘text1’];
{switch back to form, type “Hey Let’s Go!”}
And so you see that my data has been submitted to the server. My own recommendation is that you rely on POST when posting, and GET when passing through the URL.
By the way, if you try this out yourself, and you see forward slashes in front of your apostrophes, it means that your php installation has magic quotes turned on. If that’s the case, I recommend you read the PHP manual under security to learn what magic quotes are, and decide if you want to turn them off. It’ll give you instructions on how to do it. The feature is deprecated in PHP 5.3 and removed in PHP 6, so turning it off is the best option if you’re not already working on a site that relies on them.
Now, back to the name attribute here, you can actually use square brackets in the name itself to specify that the value is part of an array. I’ll prove that now:
{modify name attribute to be text1[key1][key2]}
echo ‘POST[text1][key1][key2] = ‘ . $_POST[‘text1’][‘key1’][‘key2’] . ‘<br>’;
And you can see that that works. I don’t have to use associative arrays either. If I wanted, I could have ten different elements all named like ‘var[]’ and they would automatically get set as a numerically-indexed array within POST called var.
Moving on, the hidden element has another attribute. Technically all of the input elements support it, but I ignored it with the text type. It’s the value attribute. The way hidden works is it sends a name/value pair to the server without any input needed from the user. Pretty simple right there.
The radio element is designed to work with other radio inputs that have the same name. Your script specifies a value, but that value only gets sent to the server if the radio button is checked. And with other buttons of the same name, the browser is responsible for ensuring that only one of the elements can be checked at a time.
{show radio button clearing another radio button}
Since each button has the same name, my script can tell which one was checked based on the value that gets passed with that key.
Checkboxes are similar. You don’t have them all named the same, although you can. But more than one can be submitted with the same name. The way all these inputs work is that if an element lower down on the page sends a value corresponding to the same key then only the latter element actually ends up in the POST array. Of course, that’s not counting ones with empty square brackets at the end – have as many of those as you want and they just keep getting appended to an array. And in fact, that’s not an uncommon thing to do with checkboxes. But if you have either radio buttons or checkboxes where none are checked, they don’t get submitted to the server, so a common use for hidden elements is to place them above your checkboxes in the code. That way, you can send a value to the server letting your form processor know that the box was left unchecked. But if the checkbox is checked, its value will be the one that shows up instead.
Anyway, my checkboxes are simple. They have names and all their values are 1’s. Above them all is a hidden field with the same name and a value of 0. So, my form processor knows whether they were checked or not. Because input elements lower down will override elements with the same name higher up on the form, the hidden element’s value will only get transmitted to the server if the corresponding checkbox is unchecked. But if the checkbox is checked, its value will be sent to the server instead.
if($_POST[‘cb1’] == 1) {
echo ‘cb1 was checked’;
} else {
echo ‘cb1 was not checked’;
}
The last input type is the submit button. I’ve been using it each time I’ve submitted the form, so let’s look at how it gets created:
<input type=”submit” name=”B1″ value=”Submit”>
The ‘value’ attribute is what shows up on the button when your user looks at the form. As for the ‘name’ attribute, it’s optional, but if I provide it, I can access the button’s value in the POST global through my PHP script. The ‘submit’ button isn’t the only way to create a button through HTML, but it has the special property that when your user clicks a submit button, it causes the form to be submitted. And if you have several different submit buttons on your form, you can check the POST array to find out which one was submitted. The submit button’s value only gets sent if the user clicks it. If it’s just on the page, but not clicked, then the POST array doesn’t get any information from it.
<input type=”submit” name=”B1″ value=”I am B1″>
<input type=”submit” name=”B2″ value=”I am B2″>
<input type=”submit” name=”B3″ value=”I am B3″>
<input type=”submit” name=”B4″ value=”I am B4″>
if(isset($_POST[‘B1’])) {
echo “You clicked B1”;
} elseif(isset($_POST[‘B2’])) {
echo “You clicked B2”;
}elseif(isset($_POST[‘B3’])) {
echo “You clicked B3”;
}elseif(isset($_POST[‘B4’])) {
echo “You clicked B4”;
}
{add the code shown above, click the form a couple times to prove it works}
So, that’s about it for forms. There’s more to them than what I’ve introduced, but this should be enough to get you started.
March 07 2010 | Schmategories | Comments Off on Getting Data from the user – part II
PHP includes a number of convenient built-in functions. These built-in functions are written in C, and are all faster than what you could accomplish with a custom function written in PHP.
The set of functions I want to introduce you to in this video all deal with your variables and what they are.
The first function is called ‘isset’. ‘isset’ will return true if you call it on a variable that has been assigned to a non-null value. Unlike most other PHP functions, isset is actually a language construct. For most purposes, there isn’t much distinction between it and the other built-in functions. However, it’s worth pointing out that you must invoke it on a variable, even one you haven’t yet declared. If you try invoking it on a string or an int or the return value of another function, your script will fail to execute, and even with error reporting enabled, you won’t see an error notice.
{show isset being called with a literal}
Generally mentioned in the same breath as ‘isset’ is the function ‘unset’. unset is also a language construct, and also cannot be called on anything other than a variable. All it does is clear a variable’s contents and remove it from memory. If you try accessing that variable again later, it’s value will report as null.
The last language construct in this set is the function ’empty’. In some sense you can think of it like the counterpart to isset. Again, it can only be called on a variable, but instead of telling you whether a variable is set, it tells you whether that variable evaluates to false. So, if you set a variable to either null, the empty string, the boolean false, an empty array, or the number 0 it will return ‘true’, because when PHP converts any of those to booleans they all evaluate to false. I know, the logic sounds a little backwards when I explain it that way, but that’s how it works. If you test a variable with any value that evaluates to true, ’empty’ returns false.
The next set of methods can tell you much more about what a variable actually is, and these are not language constructs, by the way. Whereas language constructs are the lowest-level elements of the PHP language, the rest of these functions (like most functions PHP provides) are built up from a combination of C code and the language constructs. As far as your everyday coding goes, if you use Zend Studio, as I do, it just means that they don’t get colored blue automatically when you type them. You could also invoke them on literal strings or ints, the return values of other functions or whatever, and not just actual variables, if you were so inclined.
Now, I’m going to go through these kind of fast, but one of the nice things about these functions is I can just introduce them by name and it’s obvious what they do. So, first we have is_array to test whether a variable is an array. is_object tests whether something is an object. is_resource checks for resources. We talk more about objects in a later chapter. You can use is_scalar to test for something that’s neither an array, a resource, nor an object. is_numeric tests for numbers, whether they’re ints or floats. If you just want to test for a float, you can use is_float or is_double (they’re exactly the same functions). If you just want to test for ints, you can use is_int, is_integer, or is_long (all 3 are exactly the same function). is_string tests for strings. is_boolean tests for booleans. There’s even a function to test for nulls called ‘is_null’. Functionally, is_null is the exact opposite of isset, except that it won’t crash your script to call it on a literal or on the return value of another function.
At this point you’ve probably noticed a pattern. If you just start searching for functions starting with the prefix ‘is_’ you’re going to find a whole lot more just like the ones I’ve mentioned.
{bring up PHPfr showing all functions with the ‘is_’ prefix}
Every different variable type has an ‘is’ function associated with it. And there are very useful ‘is’ functions to test for things like whether or not a particular constant has been defined, whether a particular directory is writable, whether an object is an instance of a particular class or sub-class, whether the filepath you’re working with represents a file that’s been uploaded from a form. The list isn’t exactly endless, but it’s pretty darn long. All of these functions perform some sort of test on your variable and return true or false depending on the test and the variable. The ones I’ve mentioned are probably the ones you’ll use the most, but they all have their place once in a while.
If you don’t want to run a true-false test for the type of a variable, but just want the variable directly, use ‘gettype’. It has 8 possible return values:
{bring up PHPfr page for ‘gettype’}
array
int
double – we usually call these floats, but it’s returned as ‘double’ for historical reasons
string
resource
object
boolean
null
February 04 2010 | Basics and Built-in PHP functions and PHP tutorial scripts and Schmategories | Comments Off on Basic Language Functions
PHP was initially envisioned as a way to get dynamic content onto a webpage. And to that end, the creators assumed their users would write a website in HTML, and then intersperse PHP code at different points within those pages in order to let them adjust to different situations. And it should be noted, PHP still works great for that.
But when PHP 3 was released, some engineer decided to add very simple, very basic object support. And it wasn’t even object support the way most object-oriented languages would describe it. Yes it was a way of keeping a collection of functions and variables inside a separate scope. But under the hood, it was really just associative arrays powering it all.
But surprisingly, a lot of PHP developers started playing with objects, and they liked some of the things they could do with them. So, over the years, PHP has started to look more like a traditional object-oriented language. Now, pretty much any design strategy you can accomplish with a mainstream OO language like C++ or Java, you can implement in PHP.
A question I hear a lot from people starting out with PHP, is “Does this look like a project where I should pursue an object-oriented approach?”
The answer depends on a number of factors.
The first point I should get across is that there is a performance penalty when you use objects in PHP. There is some overhead PHP needs to add in order to create objects, and if you were to design 2 separate websites that did the exact same thing, down to the last instruction, but one did it all procedurally, and the other used objects, the procedural site would be measurably faster.
So, when deciding whether to use objects, the first question you have to ask is what will you gain that makes the performance penalty, albeit a small one, worth it?
Well, first off, objects let you abstract out portions of your code. That means that you can have objects that pretty much take care of themselves, and when your code interacts with them, it doesn’t need to know exactly what they’re doing in order to use them. This means that if you want to change how one part of your project works, it can be decoupled from other parts to such a degree that those other parts won’t also have to be modified. At least, not in most situations.
The second advantage objects can infer is the ability to avoid code duplication. Code duplication can happen when you have particular tasks that get done many different times throughout your code. Now, some of the problems with duplication can be effectively dealt with by using custom functions. And functions don’t have the same overhead as objects. So if your project is small enough that, with a manageable number of functions you can avoid code duplication, then that’s probably the best approach. But when that list of functions becomes very difficult to manage, then much like organizing your computer’s files into folders, organizing your functions into class methods can make your development much easier.
The last advantage is that, once you get the hang of objects, it’s actually much easier for most programmers to envision their data and logic as distinct objects. And if it’s easier to understand how your application or website is built, then it will be easier to bring other people onto your project. So, whenever your project is going to be large enough that multiple people will be working on it, objects are almost always going to be worth the overhead.
February 02 2010 | Schmategories | Comments Off on When to use object-oriented versus procedural programming
One of the most difficult parts about understanding someone else’s code arises when their coding style follows a different set of conventions than you do, or worse, no conventions at all. To help developers approach one another’s code more easily, the most common coding conventions have been gathered by the helpful people at Zend into a set of coding standards that you can employ to help ensure that the greatest number of people will be able to easily follow your code. I’m just going to introduce you to the standards they recommend. I won’t try to cover every detail – it’s a fairly long document – but if you want to learn more than just what’s in this video, check the file included with this presentation.
The coding standards suggested by the engineers at Zend have been released to the public under the same BSD license that covers Zend Framework, which means anyone can distribute or modify it to suit their needs. However, I am supposed to keep the copyright statement with it. Very briefly, here’s their license:
{show slide ?} http://framework.zend.com/license
The first topic covered by the coding standards is file formatting. Probably the most important takeaway from this section is the fact that files containing only PHP code must not contain a closing PHP tag ‘?>’ because it could risk introducing whitespace. New programmers in PHP often don’t realize this, but you don’t need to end your PHP scripts with any tags. The only reason you should need the ‘?>’ tag is if you’re mixing non-PHP code, such as HTML, with your file. And if you do introduce whitespace, say while including a file before the headers are expected to be set, it can screw up your script’s calls to start_session, header, or set_cookie functions (among other things).
Other points in this section – use 4 spaces to indent your scripts rather than tabs (since tabs can render inconsistently across editors) and line-lengths should be limited to 80 characters as much as possible, and have an absolute limit of 120 characters. This just prevents line-wrapping from making your code hard to read. And the last thing it mentions is how lines should end with a single newline character – the ASCII character 10, hex character 0X0A. Now, I’ve set up my code editor environment to implement each of these conventions. If you use Zend Studio, here’s how I set my editor to follow these conventions:
{open text editor settings page}
I got here by going into my preferences, then selecting ‘General’, ‘Editors’, and then ‘Text Editors’. Notice I set my ‘displayed tab width’ to 4, and checked the box for ‘replace tabs with spaces’. That lets me use tabs while I code, but actually inserts spaces. And then lower down I checked the option to display print margin, and set the margin to 80 characters. It shows up as a thin gray line in my editor that I try to keep my code inside as I write it.
Last, to get the correct line ending characters, I selected the workspace menu, and switched my new text line ending character from default to ‘Unix’.
The next section in the Coding standards deals with naming conventions.
Classes should be capitalized. And the name of the class should match the name of the filepath where the class can be located, with the underscore character in place of the path separator.
So, the class ‘Report_Display_Column’ would be located in the file Report/Display/Column.php. Personally, however, I follow the convention of ending my class-containing files with ‘.class.php’. The standards used by Zend make no preference either way, so don’t feel like you need to do the same. I just think it makes it clearer for you when you’re reviewing the files I’ve included with a lesson.
Each character immediately after an underscore should also be capitalized, and there should be no cases of consecutive capital letters. So, for example, ‘Report_Display_HTML’ would be an invalid classname, but ‘Report_Display_Html’ would be fine.
Other PHP files that do not contain classes should always end in .php, and filenames may only contain alphanumeric characters, the underscore, and the dash. Spaces in filenames are singled out as being very bad.
When it comes to naming your functions and methods, they should always being with a lowercase letter, and consist of only letters and numbers. However, numbers are discouraged unless there’s a really good reason. For instance, if you think ‘html2Text’ is more readable than ‘htmlToText’.
When a function name includes more than one word, it should be written with the follow-on words capitalized. In developer-speak this is often referred to as camel-case. And verbosity is encouraged. A long function name that clearly identifies what that function does is a good thing. In the case of a class method that has been declared private or protected, its name should begin with the underscore character. And that is the only case where it is appropriate to have the underscore character in you method names. The ability to set visibility on your methods and properties is new in PHP 5, so if you’re not familiar with this, don’t worry, since it gets covered in another section of this tutorial.
As for variables and class properties, they follow the same rules as functions. Camel-case with descriptive names. Very short names like $i or $n are permitted only in the situation of very simple loop counter variables. And, as a general rule of thumb, ‘very simple’ means 20 lines or less. If your loops go longer than that, then even your loop counter variables ought to have longer names.
One other note, if a class property is declared private or protected, it should begin with an underscore, just like a private or protected class method.
The last naming convention applies to constants, and that includes class constants and constants created with the ‘define’ function. They should be named with all capital letters, and if a constant’s name consists of more than one word, the words should be separated with underscore characters. Use descriptive names to make it easier to understand what a constant is going to be used for.
February 01 2010 | Schmategories | Comments Off on Coding Standards – part I: File format and naming
PHP 5.3 introduced the ability to create and use functions on the fly without naming them. When this technique is employed we refer to those functions as anonymous. Probably the most common situation for anonymous functions are when you need to specify a callback function. Here’s an example:
{show example with usort}
This example takes an array and sorts it alphabetically by last letter, rather than first. The usort function is one of many built into PHP that accepts a callback function.
You don’t have to use the PHP built-in functions to use anonymous functions though. You can create your own functions and methods that accept functions as parameters. Here’s one example:
{show example}
However, you can get the exact same behavior in both cases by declaring the function normally and passing a string representing the name of the function. One reason why you might prefer anonymous functions is that you don’t have to worry about naming collisions. Two functions can’t have the same name in PHP or a fatal error gets thrown.
If you want to access your anonymous function multiple times, you can assign it to a variable, like this:
{show example}
Technically, the variable $myFunc is an object of the PHP internal class Closure. The Closure class cannot have properties and has no callable methods. So, from a practical standpoint, using it is little different from having a string assigned to your variable that represents a function’s name. The only difference is that you aren’t at risk of having a naming collision with another function, and if you call ‘is_object’ on it, it’ll return true.
If you want to do recursion with an anonymous function, you’ll need to accept an argument that represents your function. When invoking it, just pass the variable representing your function as that argument. Here’s the classic factorial function as an anonymous function:
{show example}
You can use type-hinting to ensure that you’ve been passed a function. Just type hint as ‘Closure’. But there isn’t a way to be sure that you’ve been passed the same function, so recursion with anonymous functions definitely has its drawbacks.
PHP provides a handy method to use to test whether a variable can be invoked like a function before you make the attempt. It’s called ‘is_callable’. Technically, it accepts 3 arguments, but simply passing in the variable you want to test will get you a true/false response as to whether or not you can use it. Here it is in some code:
{show example}
Anonymous functions allow you to be very flexible with your coding. If you’re a fan of design patterns, anonymous functions are a handy way to implement the Command pattern. That’s one where you set up an implementing object of some sort that takes and invokes commands, without needing to know anything about them. As the name suggests, it’s a good pattern to use when you need the ability for your objects to do lots of different things that can’t all be defined in advance.
January 31 2010 | Schmategories | Comments Off on Anonymous functions
In this video, I want to introduce the basic SQL syntax for Select statements. In all likelihood, 90% of your queries you’ll need for your dynamic website can be handled by knowing just a very few SQL statements.
The most basic Select statement is:
SELECT * FROM `Table`
This returns a result set that contains every column of every record in `Table`. Now, using PHP, you could slice, sort, and filter those results any which way you please. And there are some rare situations where that’s probably your best bet. But for 99% of all cases, you’re much better off, performance-wise, doing that sort of manipulation to your data directly in your SQL query.
For instance, suppose we only need a subset of the results in a table. There are 2 ways we can limit our results. The first way is with a WHERE clause. That might look like this:
SELECT * FROM `Table` WHERE `productID` = 15
In this case, only records with a produceID column value of 15 will be returned. And filters can be as simple as the one above or much more complex. In addition to the ‘=’ operator, you can use != to specify that a column should not match the expression, as well as ‘LIKE’ or NOT LIKE with text values to do the same thing. Your WHERE clause can even use regular expressions with the EREG operator. And you can combine as many different WHERE clauses as you like using AND, OR, and XOR, along with parenthesis. For now though, we’re keeping things simple.
Now, one other way we can limit our results is to use a LIMIT clause. A LIMIT clause will work with or without a WHERE clause, and it will simply return up to the number of results specified. Here’s one example:
SELECT * FROM `Table` LIMIT 10
This result set will contain only the first 10 records in Table. And combining it with the WHERE clause from before, we get:
SELECT * FROM `Table` WHERE `productID` = 15 LIMIT 10
Just so you’re aware, the order of these fields does matter. A LIMIT clause always comes at the end of a SELECT statement. In this case, we’ll get a result of just the first 10 records where productID is 15. And if there are less than 10 records that match, all of them get returned.
Now sometimes, in fact usually, we’ll use a LIMIT clause that lets us specify records other than just the first ones that match. For example:
SELECT * FROM `Table` WHERE `productID` = 15 LIMIT 20, 10
In this case, we get records 20-29, instead of 0-9. The first number tells MySQL which starting record to return, and the second number is how many records to return from that point.
However, sometimes we want to order our results by a specific column, and MySQL lets us do that too with the ORDER clause. The ORDER clause always comes near the end of a SELECT statement. Only the LIMIT clause can come past it. Here’s a simple example:
SELECT * FROM `Table` ORDER BY `name`
The result set will be all of the columns and all of the rows, ordered by the column `name`. Assuming `name` is a string, such as a VARCHAR, the results will be ordered alphabetically. If we want to have them ordered reverse alphabetically, we can instead use:
SELECT * FROM `Table` ORDER BY `name` DESC
And the ORDER BY clause can actually specify more than one column. For instance, suppose there was a match in more than one record. To determine the order of records that have the same value for the primary sorting column, you can specify a secondary sorting column. So, let’s say we want to order `Table` by `productID` first, and by `name` second. That just looks like this:
SELECT * FROM `Table` ORDER BY `productID`, `name`
And now let’s combine the ORDER BY clause with WHERE and LIMIT
SELECT * FROM `Table` WHERE `productID` = 15 ORDER BY `name` LIMIT 10, 5
What happens here is that MySQL pulls out all the records that have a productID value of 15, orders them alphabetically by their name columns, and then from that set, returns the 5 records 10-14.
Now, supposing you only wanted a few of the columns returned, and not every column in every record for your result set. Just replace the * with the names of the columns you actually want. For example:
SELECT `name`, `productID`, `date`, `supplierID` FROM `TABLE`
Now I’m back to getting every record in my table, but for each one I only get the columns for `name`, `productID`, `date`, and `supplierID`.
That’s it for part 1 of building SQL SELECT queries. In part 2 we’re going to look at what you do when you want to get data from multiple tables instead of just 1.
January 30 2010 | Schmategories | Comments Off on Basic SQL Select queries
As we’ve already seen, PHP has introduced a lot of new features to support object-oriented programming. The one we’re looking at now deals with a special concept known as abstraction.
Now, abstraction in OO terms is similar to what it means in regular language. We talk about something being abstract when we deal with general patterns or themes, but no concrete details. And just like in life, PHP coders use abstraction to identify fundamental strategy and overarching design without getting bogged down in the nitty-gritty implementations.
When it comes to classes and objects, there are two key tools to explicitly support abstraction provided by the PHP 5 language. Interfaces and abstract classes.
We’ll start by taking a look at an abstract class. A class is abstract if it contains abstract methods. And a class can contain abstract methods by either explicitly declaring them or by extending a class with abstract methods and then not defining them.
The keyword you use on the class is, simply enough ‘abstract’. You use the same keyword on the methods. Here’s a simple abstract class that defines one abstract method:
{show example code}
Notice that the abstract method declaration looks sort of like a regular method declaration, except it contains the keywork ‘abstract’ in the front and ends with a semi-colon instead of braces. That’s because it only defines a method’s name and arguments, and not any of its implementation.
The idea here is that you might have many different child classes that extend an abstract class and implement its abstract methods in various ways. Without knowing the specific implementation, your other objects can interact with those child classes.
Now, the important thing to understand is that you cannot get a new instance of an abstract class. PHP will only create objects of non-abstract classes. If you want the functionality that an abstract class provides you must extend it into a non-abstract class that defines all its abstract methods.
For instance, if I define an abstract class called ‘Report’ with an abstract method called ‘display’, my other scripts know that regardless of which type of report I might have, it will always be able to display itself. I might define a Report_HTML child class for displaying a report inside an HTML table. I might define another one called Report_CSV for outputting a version of a report that can be saved in a CSV file. And I might define another one called Report_XLS for saving a report to an Excel Spreadsheet.
The point is that there are going to be many different scripts involved in getting data to the report or working with the report, and most of them don’t need to know how the report is going to be displayed in order to do their work correctly. So, rather than creating completely separate classes for each situation, we create one report class that has just one abstract method that needs to be defined separately in its child classes. This lets us use the same code in as many locations as possible, and code re-use leads to easier maintenance and management.
Since I like to point out design patterns from time to time, this is a good time to mention one called ‘Decorator’. The Decorator pattern is probably the one most often used by programmers who don’t even realize they’re implementing an actual named pattern. All it is is using child classes to add more specific functionality to parent classes. Extending an abstract class is one obvious way to accomplish that.
The other abstraction tool is similar. While abstract classes are essentially regular classes that happen to have some abstract methods, interfaces are sort of like classes that only have abstract methods. Interfaces don’t define properties, though they can define constants. And while a class can only extend one parent class, abstract or otherwise, it may implement any number of interfaces.
Here’s how we define an interface:
{show example code}
Notice that it really does look a lot like a class definition. You don’t need the ‘abstract’ keyword on the method declarations, but they do resemble abstract methods nonetheless. And since the basic idea is that an interface defines a way for other objects to interact with them, interfaces may only define public methods.
To tell the PHP engine that a particular class is going to implement the methods defined in an interface, we use the keyword ‘implements’ in our class definition. And if a class implements multiple interfaces, we just separate them with commas. However, no class can implement two interfaces that both define the same method name.
Interfaces can extend interfaces, and in fact, they can extend multiple interfaces. To extend an interface, you just use the extends keyword, and to extend more than one interface you just separate them with commas.
{show example code}
One thing to note about interfaces is that since there’s no actual code, it is vitally important that you comment them fully. The method declarations on an interface tell the programmer the method’s name and the arguments it should accept, if any. But if one of those methods should return something, the only way to let the programmer know that is in the comments. Here’s an example of a well-commented interface:
{show example code}
Notice that each method’s comments clearly explain what the method should do, in broad terms. With this documentation, it is feasible to begin writing code that will use objects that implement a certain interface even before the implementing classes have been defined.
Objects of classes that extend abstract classes or implement interfaces are considered to be instances of those abstract classes or interfaces, the same as they’re considered instances of the classes that define them. This makes it possible to use type-hinting to specify that your functions and methods require specific interfaces or classes as arguments.
To understand how powerful type-hinting is in connection with abstraction, imagine you have an interface called Readable. Among other things, it defines a method called ‘readLine’ and another method called ‘hasNext’. ‘readLine’ is responsible for returning a string from some content source, and advancing an internal pointer, so that a subsequent call to ‘readLine’ will get the string that comes right after. The ‘hasNext’ method returns true if there is are any lines left to get, and false if there aren’t. Knowing just those two methods, I can write a function like:
{show example code}
My ‘writeFile’ function knows that it’s getting a Readable as its first argument, and will write it out to whatever filename it’s told to. It doesn’t matter if the particular Readable is based on another file, a stream, the contents of a database, or anything else. And I can trust that so long as my various Readable implementations correctly return the data they ought to, my writeFile function will work with any of them. This sort of versatility means I can create functions such as writeFile before I’ve even created the actual object types that will be passed into them.
So that’s abstraction in a nutshell. You create abstract methods with lots of documentation to explain what they’ll do, and then you write classes that define those methods in a concrete, useful way.
January 30 2010 | Schmategories | Comments Off on Abstract classes and interfaces – part 1
In PHP, programmers can take advantage of an unusual technique known as variable variables. Basically, if you have a variable named $one that equals the literal integer ‘1’ and then another variable named $first that had a value of the string ‘one’, then the value of $$first would resolve as the literal integer ‘1’.
Here, check it out:
$one = 1;
$first = ‘one’;
echo $$first;
{show output}
The 2 dollar signs together are what tell PHP to return the variable $one instead of just $first. It is possibly the most confusing single thing in PHP, and something that new developers are understandably thrown by the first few times they see it. It’s not something you see a lot, but when you do see it, it’s usually because the developer was trying to solve an unusually difficult problem.
Variable variables work on both sides of an assignment too. If I were to write:
$second = ‘two’;
$$second = 2;
A new variable ‘$two’ would be added to my scope, such that if I were to say:
echo $two;
I would see ‘2’ in the output. And yes, that confuses everyone at first. I’m still confused by some of this stuff.
One of the things I find most interesting in PHP is that you can also use variables to invoke functions. Check out this example:
$test = ‘hello’;
function hello() {
echo ‘Hello World’;
}
$test();
{show output}
And so you see that I can now use a variable to invoke a function.
As far as naming restrictions, the variable $this is reserved, and can’t be used in variable variables. And with variable functions, it won’t work for special built-in PHP functions known as language constrcuts. These include ‘echo’, ‘print’, ‘isset’, ‘unset’, ’empty’, ‘include’, and ‘require’. Other than that though, you’re pretty unlimited. And variable variables don’t even need to be legal variables. Check out the following code:
$test = ‘1test’;
$$test = ‘hello’;
echo $1test; //variable names can’t begin with numbers – get a fatal parse error
You’ll get a fatal error, but if you really want to, you can do the following to see that PHP really did create your variable, you just can’t use normal PHP syntax to view it directly because of the rules around variable names. What you can do instead though, is this:
echo ${‘1test’}; //prints out ‘hello’
That last example introduced you to the power of braces in PHP. PHP can do quite a lot with braces as an intermediate step. If you place a dollar sign in front of a statement in braces, and then place an expression inbetween the braces, whether mathematical, scalar, evaluable function, whatever – if the result can be turned into a string (other than the string ‘this’), PHP will use that result as though it were the name of a variable you were attempting to access. And expressions in braces can be nested.
Though, from a practical standpoint, that’s a good way to make your code a lot harder to read!
${”} = ‘Empty!’; //the empty string can be a variable!
${${”}} = ‘Weird?’; //nesting brace expressions looks weird!
${${${”}}} = ‘Spooky!’; //double nesting just looks downright spooky!
echo ${‘Weird?’};
echo $${‘Empty!’}; //prints out ‘Spooky!Spooky!’
{show output}
Now, this last example brings up an interesting point about the empty string as a variable. Consider the following:
${null} = ‘Hello’;
echo $$notSet;
The variable $notSet was, as its name suggests, not set anywhere in the code. When PHP looks at it for the first time, it gives it an assumed value of null. Unlike more strictly-typed languages, you can use a variable in PHP without declaring it or setting a value to it. It’s just null until you make it something else. And null can be cast a string – the empty string. So here’s the output to that example:
{show output}
This leads to one way to seriously make your code confusing. When someone looks at your code for the first time, trying to understand it, one of the first things they’ll do is look to see where a particular variable is declared. But consider a script that did this:
$$somethingStrange = ‘Hello’;
//lots of intervening code
echo $$lostYa;
If neither $somethingStrange or $lostYa were declared in the code, then what you actually get is the empty string being used as a variable to save the value ‘Hello’ and then getting invoked when the script echoes $$lostYa. Here’s the output to prove it:
{show output}
Even worse, if you defined a function called ‘Hello’, then you could invoke it by doing something like:
$$somethingStrange = ‘Hello’;
function Hello() {
echo ‘Hello World. How do you suppose we got here?’;
}
$$hahaYouDontKnowWhatsGoingOn();
Hopefully you’ll never need to deliberately make your code hard to understand, but if you do, just treat the empty string variable as a part of your code, and keep invoking or setting it with a different undeclared variable every single time. I’m sure it would quickly drive me nuts if I saw it. So actually, on second thought, let me just advise you to never ever do this, but if you see it in someone else’s code, then that’s what they’ve done.
Anyway, moving back to the subject of braces, they can sometimes be the only way to resolve ambiguities, such as when your variable variables involve arrays. Consider this example with no braces:
$$one[2]
How is PHP supposed to interpet that? Do you want to get the value of $$one and then get the value at its array index 2? Or do you want to get the value of $one[2] and then use that result as a variable? Without braces, PHP can’t do anything with that expression. If you want to use $$one as your variable, use:
${$one}[2]
If you want $one[2] as your variable, use:
${$one[2]}
Here’s both examples:
{show script}
{show output}
Variable variables have been part of PHP since at least as far back as PHP 3. However, the engineers have continued to innovate, devising more ways to let you use variables in place of the names of other variables, particularly now that PHP has added so much object support.
The first one, which has been supported at least since PHP 4, is variable properties. When you refer to an object’s properties, you usually use an arrow pointing to the property name, like so:
$obj->one
However, if we again assume that the value of $first is the string ‘one’, then you can point to the same property with:
$obj->$first.
Now, that’s how it looks in PHP 5. In PHP 4 you had to place braces around your variable, like so:
$obj->{$first}
That just tells PHP to evaluate the bit inside the braces first. But since PHP 5, the engine will do that even with the braces removed (though obviously braces don’t hurt, either).
Building on that, PHP 5 also introduces the ability to refer to method calls by a variable. So, if we want the call
$obj->one()
We can now use:
$obj->$first()
Wild, isn’t it?
{show output}
The latest versions of PHP don’t even stop there. In PHP 5.3, the engineers decided to support variable class names! So, if ‘One’ is a class, and $first is the literal string ‘One’ , then the following code will create a new object of your class:
$obj = new $first();
Isn’t that cool?
I wish I could name a common problem that these techniques solve, but really, it’s just one more thing in your toolkit, and there’s no telling when you’ll reach for it. But if you know this little secret, then every so often you’ll see some tricky problem, maybe involving a sort or a switch, where variable variables turn out to be a great way to build your solution.
I know this is a difficult topic to grasp at first, but once you accept that aliasing can be used in place of actual variable and function names, it starts to make a certain sense. On the other hand, if you find yourself still not able to grasp it, I can at least reassure you that everything else in this tutorial is easier.
January 27 2010 | Schmategories | Comments Off on Variable variables
While there are many changes to PHP 5 that I love, if I were forced to choose a favorite, it would probably be this next thing I’m going to show you. It’s called autoload, and what it lets you do is define a way of including files dynamically based on the names of classes that your scripts need to use.
The basic idea is you devise your own class-naming convention such that based on the name of any given class in your project, you can say which file holds it. And then, you create a function named __autoload that takes the name of any class and builds an include statement that ought to give you access to it.
This lets you be sure that only the files that need to be included actually are, rather than having to include every single file that might possibly hold a class that some part of your script will need later. And best of all, you create the function once, and then so long as you keep your naming convention, you never need to think about including class files again!
Probably the most common classname convention is where you represent directory separators as underscores in your class names. So, for instance, if your class is named ‘Really_Big_Long_Class_Name’ then it probably resides in really/big/long/class/name.php. Personally, I tend to use a variant of this convention, where instead of ending my class files with .php, I end them in .class.php. So anyway, here’s what the __autoload function that does that might look like:
{show example code}
However, there is a drawback to this technique. Namely, if you define a function __autoload, you can only have one autoloader function. That might not sound like much of a drawback, but think about what happens if you want to make or use a 3rd-party plugin. Well, a plugin needs to define how its own classes are going to be included, and redefining its own __autoload function for the entire website isn’t going to fly. Technically, it’d cause a fatal error if the __autoload function has already been declared somewhere else. Like any other function, you only get to define it once.
So for more complicated websites, you either go back to including all your class files manually, or you switch to the very cool spl_autoload_register function.
spl_autoload_register lets you define a stack of functions that each get checked, one at a time, in order, until the class sought is found. You can call it as many times as you like, adding a different path conversion algorithm each time. This is the strategy I recommend you use in your own code.
Now, I haven’t called your attention to it, but you may have noticed that in almost every script I’ve written that tests some class or another, I have a single include statement. All it says is include ‘autoloader.php’; . And my classes get imported correctly every single time.
Let me show you how autoloader.php actually works. Notice, I DON’T use the code example I just showed you. I could, and it would work, but this is something even better.
Remember how I said that the convention of representing directory separators as underscores in the class name is the most common one? Well, it’s SO common, that the PHP engineers provided it as a default. When I called spl_autoload_register with no arguments, it told PHP to go ahead and register its built-in autoloader. Because it’s actually built into the language, and coded in C, rather than PHP, this is actually going to perform file includes faster than the exact same algorithm coded into a PHP function.
There’s a couple other important lines in here. The first line, ‘set_include_path’ was necessary to make sure that my classes directory, where I’m keeping all my class files, is one of the include paths PHP checks when I try to use the include statement. The other line, spl_autoload_extensions, tells PHP that my class files will end in .class.php.
And that’s really it! If I want to use the exact same naming convention, but separate my class files into several different folders, I would just need to call the set_include_path again for each folder that might contain a class file.
January 24 2010 | Schmategories | Comments Off on The Autoloader
Design patterns are the techniques programmers use for solving some sort of programming challenge using objects. There are many, and I’d encourage you to learn more than what these videos have space to teach. But out of them, 2 of the most commonly used are called Singleton and Factory.
The simplest of these is the Factory pattern, here’s one way to represent it:
{show code example}
Like I said, very simple – a Factory pattern exists whenever you use one class to create another. But it can be extremely powerful. Essentially, it has your code avoiding the new statement for certain types of objects, and instead relying on a specialized class to build them for you.
The purpose of the Factory pattern is to make your job as a programmer simpler. The example I just showed you is sort of a silly one. With objects that simple to create, there’s not much point in using the Factory pattern. But this technique becomes very useful when the constructor for an object takes many different, complex arguments. Instead of looking up all the information needed to construct one of those objects every time, your Factory class builds them for you and sends them back to your scripts ready to use.
By employing the Factory pattern, you create a situation where one part of your code doesn’t need to know about what another part of your code does. And that’s when object-oriented programming gives you the greatest benefit. By making different parts of your code work without any need to understand what another part does, you can more easily expand functionality in one area without having to completely rewrite others. That also makes it easier to debug, and more effectively tackle a project as a team.
The next design pattern I want to look at is the Singleton, and it gets its name from the fact that, when you use this pattern, there can only be one instance of your class running at any given time.
{show example Singleton}
The basic way it works is you have a constructor that’s declared as private, and a private static variable, usually called $_instance. Then, you have a public static method called ‘getInstance’.
Because the constructor is private, you can’t call $obj = new Singleton() anywhere outside the class itself. When you want to get an instance of Singleton, you go through the Singleton::getInstance() method.
The getInstance method, since it’s on the Singleton class, is allowed to call ‘new Singleton()’. So, when you put in a call to Singleton::getInstance() it first checks to see whether self::$_instance is null or not. If it is, it says ‘self::$_instance = new Singleton();’. Next, it returns the value in self::$_instance.
And that’s really all there is to it. Since there can be only one instance of Singleton at any given time, you know that any change you make to any property on it will be still be reflected if you access it anywhere else.
Technically, in this example there’s nothing stopping your code from cloning a Singleton, but if you wanted to prevent that too, you could just create a private function called __clone. __clone is one of the magic methods php provides, and just like __construct can be used here to prevent an outside call to the ‘new’ statement, __clone can be used to prevent the ‘clone’ statement from working.
So, I created a very simple test script to show the Singleton in action:
{show test script}
And here’s the output from that:
{show output}
Notice, I call the ‘getInstance’ method twice, but the objects in both cases are actually the same. Even though I set the ‘data’ property on $singleton1, when I display the contents of ‘data’ on $singleton2, the value shows up there.
So why would you want a Singleton? Well, if there’s code you want to make sure gets run just once in setting up an object, but then have access to the results of that code all throughout your script, Singleton is a pretty good way to handle that situation.
Later on, when we look at setting up an object-oriented login system, we’ll employ a User class that’s a Singleton. We only want to check a user’s session one time per page load, so by putting that into the constructor of a Singleton, we can accomplish that. But then every time we need to get a user’s information, it will be available without having to re-check their session every time.
January 24 2010 | Schmategories | Comments Off on Basic Design Patterns – Singleton and Factory
Next »