So, you’re considering using PHP for a project, but aren’t sure where to start, or maybe even why you should use it? Perhaps you’ve heard all the horror stories about PHP being spaghetti code, bad for your health or that it’ll run slow as molasses. Don’t believe them! It’s not as bad as you think, and with the right approach, can be quite fun (and productive). Honest! Don’t believe me? Read on...
Why Use PHP?
There are a number of reasons to consider using PHP. It has a vibrant community of developers of all different levels contributing to various projects across problems in the web domain. PHP is cross-platform - the same code you write on Windows will run on PHP under Linux, Mac, AIX or other platforms.
The same code you write on Windows will run on PHP under Linux, Mac, AIX or other platforms.
Finding a PHP developer to fit your project’s needs is easy because of the large pool of talent. Finding existing PHP code to adapt for your project’s needs is also often easy.
Installing
There are a number of ways to get a full PHP stack (web server, interpreter, libraries, etc.) installed on your system, depending on what platform you’re running on.
Linux
Many Linux platforms come with PHP pre-installed, or available in the distro’s package system. apt-get install php5 or yum install php5 is often all you need to do to get started.
Mac
There are a number of projects that give you a full PHP stack on Mac. MAMP and MNPP are two to take a look at, and each will install PHP, MySQL, Apache and supporting libraries.
Windows
XAMPP is arguably one of the most popular packages for installing a full PHP stack on Windows, but it’s not the only one. Microsoft has offered PHP and many PHP apps as part of the Web Platform Installer service. microsoft.com/php will point you in the right direction. You can watch a video of an installation of PHP on Windows at http://michaelkimsal.com/phpsilverlight_v6.mov.
Zend Server
Zend is a large force in the PHP community, and is the largest commercial provider of support, tools and training for PHP. Zend offers Zend Server, a full stack which includes PHP, MySQL, and both Apache and integrated support for PHP on IIS. Zend Server is available in a free Community Edition or a paid for Professional Edition. You can find Zend Server at zend.com/server.
IDEs
The majority of IDEs out there for PHP are Java-based, furthering the cross-platform utility of PHP.
- Zend Studio is arguably the most popular, and built using the Eclipse project as a foundation. (commercial)
- The PHP Developer Tools (“PDT”) plugin for regular Eclipse installations doesn’t have all the features of the commercial Zend Studio. (free)
- Netbeans, another Java-based IDE, has offered support for PHP for a number of years. (free)
- Aptana, another Eclipse-based IDE, offers support for PHP, as well as CSS, JavaScript and more. (free)
- PHPStorm is a PHP-focused IDE from JetBrains, the people behind IntelliJ and Resharper. (commercial)
- VS.PHP is a PHP plugin for Visual Studio. (commercial)
While this list is not exhaustive, let me say that there’s not a strong need for an IDE tool, especially when getting started with PHP. It’s perfectly acceptable to use Notepad, VIM or any other text editor to write your PHP. IDEs certainly offer some nice functionality, but much of PHP easy enough to use without a full IDE.
Languages vs Frameworks
Another point to bring up about PHP - it’s often compared to ASP.NET, Ruby on Rails, Django and other full-stack frameworks. At its core, PHP is strictly a language, not a full framework, so comparisons between apples and oranges will inevitably be rather lopsided. There are some strong frameworks built for PHP which I’ll touch on, but be wary of people who say “ASP.NET can do X, PHP can’t.”
The better comparison would be to compare ASP.NET to Zend Framework, Symfony, Code Igniter or CakePHP, currently the four PHP frameworks with the largest mindshare. Certainly dozens (hundreds!?) of lesser-known frameworks exist (Kohana, Lithium, Solar, Yii, etc.), and it can be argued that many CMS tools such as Drupal and Wordpress are, in fact, domain-specific frameworks.
If you’re planning on starting a large PHP project, it would be worth your time to investigate one or more of these frameworks to find one that fits your style or that of your team. The communities that built these frameworks have solved a number of architectural problems and you’re likely better off not reinventing the wheel.
Basic Syntax
You should keep a few key points about PHP’s syntax in mind.
Delimiters
Inside a file, you need to indicate to the parser where PHP execution should begin. To do this, you use the <?php ?> delimiters. <?php acts as an opening delimiter, and any code after that up until ?> will be treated as executable code. Code outside of those delimiters will be passed through (usually to the browser). This is similar to classic ASP’s <% %> delimiters.
Variables
PHP denotes variables with a $ prefix and then start with a letter or underscore, and can be pretty much any length required. Valid variable names include $name, $emailAddress, $_phone, and $a1q17_b5qxp.
Operators
PHP does not support operator overloading, and each operator only does one type of operation, regardless of context. PHP uses the period (“.”) to concatenate strings only, and uses the plus (“+”) for mathematical addition only. This sometimes trips up people coming from other languages.
Miscellaneous
Lines are terminated with a semicolon (“;”). Whitespace is not important.
Scoping
Scoping is pretty straightforward:
- Variables defined outside of a function or class are visible only to other code outside functions or classes (known as the global scope).
- Variables defined inside a function are only visible inside that function.
- Variables defined inside a method are only visible inside that method.
What’s caused PHP problems over the years is the global keyword, which PHP uses to create direct references to globally scoped variables inside of functions and methods. It’s recommended (by me as well as others) to avoid using the global functionality for your own code.
Another wrinkle - superglobals - are a set of arrays that PHP creates for you automatically that contain server and request information, and these are available to use anywhere in your code regardless of scope. The main ones to be aware of are $_POST, $_GET, $_SESSION, $_COOKIE, and $_SERVER.
Data Types
PHP has a few core data types: float, integer, string, boolean, array, object, NULL and resource. Distinctions in other languages (hashes, lists, maps, etc.) don’t exist in PHP - we just have an array. Likewise, with numeric types - decimal, bigdecimal, short, long, double, and so on - these don’t exist in PHP. PHP only has floats and integers.
A resource is a pointer to some external entity, and most often refers to either a file on the file system or a database connection.
Infamous Hello World
You’ve got PHP and a web server installed, now let’s write some code.
<?php
echo "Hello World";
?>
That’s it! Let’s try something a bit more useful.
<?php
echo "Hello! You're coming at me from IP ";
echo $_SERVER['REMOTE_ADDR'];
echo " on ".date("m/d/Y")." at ".date("h:i:s A") ";
?>
Another way to write this as a more HTML-centric page would be:
Hello! You're coming in from
<?=$_SERVER['REMOTE_ADDR'];?>
on <?=date("m/d/Y");?> at <?=date("h:i:s A");?>
Notice the <?= ?> style used? That’s called a short tag approach. Most PHP installations support this style, but it is a parsing feature that can be turned off by a system administrator. If you’re writing something for wide distribution, it’s advised to use the <?php ?> style. However, I still use the short tag style for most of my day-to-day coding - it’s just easier for me to type.
Functions
PHP has a number of built-in functions, much of it functionality that might normally be contained within larger library hierarchies in other platforms. PHP is much flatter than that - depending on your particular configuration, you may have 1500-3500 functions all living in the global namespace.
To create your own function in PHP you use the function keyword and provide a basic function signature. Take a look at this snippet.
<?php
function getHello($name)
{
return "Hello there $name";
}
There aren’t return types available in PHP in the function declaration, which may look a little odd to those of you used to it. Also note the lack of parameter typing. We can use typing on parameters, parameters with user-defined class types, or arrays. So, for example, here is a valid function signature:
<?php
function validFunction(CustomUser $user, Array $params)
{
// do something
}
?>
And here is an example of an invalid function signature.
<?php
function invalidFunction(String $name, Object $info)
{
// do something
}
?>
Also note that when using the typed parameters, PHP will not check anything at compile time - the validity will only be checked at runtime, which may cause some interesting run-time error conditions.
Includes
One of the things that makes PHP, well, PHP, is the ability to include() code at runtime and execute it in place.
Many other languages allow for import or require to reference libraries to be included during a compilation process. PHP doesn’t roll that way.
Many other languages allow for import or require to reference libraries to be included during a compilation process. PHP doesn’t roll that way - when an include() statement is encountered, the file referenced is brought in from disk and processed accordingly. If the file included has PHP code in it (in the proper delimiters) that PHP code will be executed in the current scope and context of the including code. This next code snippet shows two separate files, with file2 including the contents of file1.
// file1.php
<?php
function getDate(){
return date("m/d/Y");
}
?>
// file2.php
<?php
include("file1.php");
echo "Today is ".getDate();
?>
Objects
PHP has had support for objects since version 4 in 2000, but the object support was revamped and expanded in 2005 with PHP5. The basics of what you’d expect - public, protected, private - are there, along with inheritance, abstract classes and interfaces. In keeping with the dynamic nature of PHP, typing is not available. A typical class in PHP might look something like the one in Listing 1.
Some functionality you may be used to which isn’t available in PHP object support includes method overloading and automatic get/set support - getters and setters would need to be manually created (although many IDEs will generate them for you).
Sessions
PHP offers automatic session management, which can be configured to start automatically or can be initiated in a request using the session_start() function.
During the initialization process, PHP will look for a session ID token in the current request, by default looking for a cookie from the user. If the cookie token exists, PHP will grab the related session information from disk, unserialize it, and place it in the $_SESSION superglobal. If the cookie token doesn’t exist, PHP will create a new one.
Session data is stored in the $_SESSION superglobal array like information in any other array. The data will be serialized at the end of a request, then unserialized again at the start of the next request.
Look at this snippet to see basic session usage.
<?php
session_start();
echo "Hello! You've been at this page ";
echo $_SESSION['visits']. " times before!";
$_SESSION['visits']++;
?>
If you’re wondering about how objects stored in session behave, well, wonder no more. Objects will be serialized just as any other data type will be, and then unserialized appropriately. The property values of the object will generally be intact, but there may be some specific things that don’t work as expected with the default behavior. You can override this by using two “magic” methods on your class definition - __sleep() and __wakeup(). If present, these methods will be called on an object during serializing and unserializing so you can modify the behavior as needed. Listing 2 illustrates what this might look like.
Templating
Frameworks such as Rails and ASP.NET have templating conventions built in to them. PHP, as such, may be more akin to a templating language itself than anything else, and many projects use “bare” PHP to that end.
Many others choose to use custom-built templating libraries for PHP which offer some convenience and security measures on top of PHP itself. One of the more well-known is Smarty. Look at this example of code using the Smarty library.
<?php
$t = new Smarty();
$t->template_dir = "/path/to/templates";
$t->compile_dir = "/path/to/templates_c";
$t->config_dir = "/path/to/configs";
$t->cache_dir = "/path/to/cache";
$t->assign("name", $_POST['name']);
$t->assign("email", $_POST['email']);
$t->display("samplepage.tpl")
?>
And here is an example of the template syntax.
// samplepage.tpl
<html>
<body>
Hello {$name} - your email you entered is {$email}
</body>
</html>
Databases
PHP provides multiple ways to access databases. For years, PHP shipped with a set of functions dedicated to specific database engines - MySQL, PostgreSQL, Microsoft SQL Server, DB2, etc. These allowed for direct procedural interfacing with most databases, but there were a number of packages that wrapped those procedural interfaces into an object-oriented approach (one of the earliest was ADODB, a conceptual port of Microsoft’s ADO approach to data access).
With the release of PHP5, PHP now ships with PDO, an object-oriented interface to the majority of supported databases. This code snippet demonstrates a basic connection and query.
<?php
$db = new PDO("mysql:host=localhost;dbname=demoSite",
"username", "password");
$sql = "select * from user where id=7";
$user = $db->query($sql)->fetch(PDO::FETCH_OBJ);
echo $user->username;
?>
Given the prevalence of SQL injection attacks, it’s probably a better idea to use a prepared statement which will do proper data escaping for you regardless of which database you’re using. Take a look at this example to see how you’d do that.
<?php
$db = new PDO("mysql:host=localhost;dbname=demoSite",
"username", "password");
$st = $db->prepare("insert into user (username, email,
phone) values (?,?,?)");
$result = $st->execute(
array(
$_POST['username'],
$_POST['email'],
$_POST['phone']
);
);
?>
A number of libraries provide more robust data manipulation libraries which build on top of the basic PDO functionality. Doctrine is a library that provides a robust ORM solution (in some ways similar to Hibernate) on top of PDO, and is being adopted by some frameworks as their default ORM component.
Testing
Given the lack of type-hinting, return types, and some other functionality which compiled-languages rely on, testing becomes even more important in dynamic languages such as PHP.
There are a couple of well-known testing frameworks in the PHP world in the form of SimpleTest and PHPUnit. While SimpleTest may fit your style (it was PHP4 compatible for far longer, ensuring PHP4 projects had a good testing framework available), PHPUnit has become the de facto standard for most of the PHP community.
PHPUnit is based on standard xUnit conventions, as are projects like jUnit and nUnit. You can create test suites composed of individual tests that interact with your code to assert specific conditions. Listing 3 contains a short example of a runnable test.
Wrap Up
I hope this introduction to PHP has given you a good idea about how PHP works. I will be the first to say it’s got its warts. From a purely academic standpoint, it’s nowhere near perfect. What PHP lacks in purity it makes up for in pragmatism and ubiquity.
Certainly there’s no reason to throw away a project you’re working on now, but it might be worth it to give PHP a spin for a future project. You may just be surprised at how quickly you can have a clean, structured, extendable project up and running with PHP.