You are on page 1of 5

PHP Scripting Intro COVER STORY

Tools and techniques for PHP with Linux

PHP SCRIPTING
PHP is becoming an essential tool for all but the simplest websites. This month we examine PHP in the Linux

environment. BY DAVID SKLAR

P
HP is at home on tiny guestbook Passing a file simply containing Hello, Hello, Slartibartfast
sites that handle six visitors a World to PHP returns Hello, World.
week, and on high-end, high-per- Mission accomplished! But what a (assuming you’ve typed Slartibartfast
formance websites with millions of visi- boring mission. into the form field).
tors a day. This open-source program- When given a file to process, PHP only This simple example illustrates many
ming language has a pleasantly smooth pays attention to the bits between the of the basic principles of PHP.
on-ramp for new programmers and small file “start” and “end” tags. The start tag
projects, but PHP also has the power, is <?php and the end tag is ?>. So a PHP Principles
flexibility, and developer community more interesting and PHP-centric Hello, The zeroth principle is that there’s an
to handle just about anything you can World looks something like the script exception to just about every one of the
throw at it. This month’s cover story shown in Listing 1. Save Listing 1 to a other principles. PHP has approximately
looks at the world of PHP. file called hello.php on a PHP-enabled 127 million different configuration flags,
In later articles, we compare some web server, and when you visit that options, directives, and other ways to
popular PHP Integrated Development page, you’ll see a form with: change its behavior behind the scenes.
Environments (IDEs). Also, we show Depending on its configuration set-
you how to find PHP scripts in online What's your name? tings, PHP intermixes error messages
archives, and we take a close look at _________________ with output, logs errors to a file, recog-
PHP development with the open source [ Go! ] nizes alternate start and end tags, disal-
Eclipse IDE. The final article examines lows access to certain functions, com-
the eZ Components library for PHP. Type in your name, hit the Go! button, plains if you set cookies after generating
First, we begin with a hands-on intro- and then you’ll see: output, and makes certain extensions
duction to PHP for the web-savvy user.
If you’re already experienced with PHP,
you may want to skip to the next story,
but if you’re looking for more back-
ground on PHP scripting, read on for a
practical introduction to the craft. We
hope you enjoy this month’s PHP Script-
ing cover story.

Hello, PHP
The traditional “Hello, World” program
in PHP is kind of a let down:

Hello, World

COVER STORY
PHP IDEs ................................................... 31
PHP Script Archives .............................. 36
PHP with Eclipse................................. 40
eZ Components................................... 44

FEBRUARY 2008 ISSUE 87 21


COVER STORY PHP Scripting Intro

The next principle is that PHP only


Listing 1: Hello, PHP cares about what’s between <?php and
01 <?php if (! isset($_POST['who_ value="Go!" />
?> – everything outside those tags is
are_you'])) { ?> 08 </form> treated as literal output.
02 09 The following PHP programs generate
03 <form method="post" 10 <?php } else { the same output:
action="hello.php">
11
04 <p>What's your name?</p> Hello, World
12 print "Hello, " .
05 <input type="text" name="who_ htmlspecialchars($_POST['who_
are_you" /> are_you']); Hello, <?php print 'World' ?>
06 <br/> 13
07 <input type="submit" <?php print 'Hello, World' ?>
14 ?>

<?php print 'Hello, ' ?>World


available or unavailable. The list of con- PHP should handle (through pattern
figuration settings in the PHP manual matching, filename extension, or some- The PHP open and close tags are com-
(http://php.net/ini) is a helpful resource thing else), the web server translates pletely orthogonal to other code group-
if your server is behaving very differ- that URL into a particular file, and then ings – you can start and end PHP mode
ently from how the examples in the arti- the web server invokes the PHP inter- inside conditional blocks, function defi-
cle say it should. preter, telling it to run the code in that nitions, and just about anywhere else in
file. PHP runs that code and generates a PHP program.
Web Server Embrace output, which is sent by the web server Third, PHP sets up arrays containing
The first principle is that PHP exists in back to the client as the response to the externally submitted data for you to use.
the warm, comfortable embrace of a web web request. Form data submitted with a POST re-
server. The typical execution model is “Standard Out” in a PHP program is quest is in an array called $_POST (vari-
that a request comes to a web server for an http response. The console is a web able names in PHP begin with the vener-
a URL that the web server has been told browser. able $). The submitted value of a form

Some Useful Information


Before diving into more code, I will sum- the multibyte extension and the tools it Then visit the page in your browser.
marize some tips and bits of background gives you for working with multibyte en- You’ll get a dump showing what exten-
information that will make your PHP codings and character sequences. PHP 6 sions are loaded and how PHP is config-
experience more pleasant. First of all, (to be released sometime before Perl 6) ured. Don’t leave phpinfo() pages wide
take advantage of the online manual at has drastically overhauled international- open for anyone on the Internet to visit,
http://php.net. ization support and a comprehensive re- however. Some of the configuration
For any built-in function or class, visit working of multibyte string handling. information could make it easier for an
http://php.net/<the function or class> If $alice is an array, then $alice[$bob] attacker to break into your server.
to get details. For example, if you’re gives you the element of $alice whose Another handy low-tech debugging tool
curious what the str_split() function key or index is the value in $bob. There’s is the built-in function var_dump(). Pass
does, hit http://php.net/str_split. not much difference in PHP between ar- the function any variable – a scalar, an
Want to know what the arguments are rays whose keys are all whole numbers array, whatever – and it will output the
for imagecolorallocate()? http://php.net/ and arrays whose keys may be strings. variable's type and value. This is handy
imagecolorallocate tells you. This is a Other languages might call them arrays, for a quick check on a variable if it is not
valuable resource in every PHP develop- maps, hashes, dictionaries, sets, lists – behaving as expected.
er’s toolbox. in PHP they’re all just arrays. Last, remember that, because you’re typ-
PHP does give you a few shortcuts if you ically viewing PHP output in a browser,
Variable names begin with $. The rest
want numeric array keys – auto-assigns the formatting of the text you’re viewing
of the variable name is a letter, numeral,
keys starting with 0: $dessert = array obeys the rules of HTML, not a terminal.
or underscore (except the first character
('icecream', 'cake'); means that $dessert If your PHP script prints out a bunch of
after the $ can’t be a numeral.)
[0] is ice cream and $dessert[1] is cake. strings separated by newline characters,
Strings delimited with ' and " behave as Plus, you can use [] to toss something you’re going to see them all crammed
you probably expect them to. Everything on to the end of an array. $dessert[] = together on one line in your browser,
is literal in '-delimited strings, except you 'candy' means that now $dessert[2] is since a plain newline character (accord-
must backslash-escape backslash and '. 'candy'. ing to the rules of HTML) does not cause
Double-quoted strings support more
If you’re having trouble with your PHP a line break.
backslash escape characters and variable
configuration or things aren’t behaving To get proper line breaks, either use your
interpolation. Concatenate two strings
as you expect, make liberal use of the browser’s “View Source” mode or have
together with a period.
phpinfo() function. Just drop a page on your code output HTML such as <br/>,
Strings are just byte sequences. If you’re your website that contains only: which tells the browser to insert a new-
working with non-ASCII data, check out
<?php phpinfo(); ?> line in the display.
http://php.net/mbstring to learn about

22 ISSUE 87 FEBRUARY 2008


PHP Scripting Intro COVER STORY

element named who_are_you is put in The isset() function in Listing 1 tells you relational database and then generating
an array element named who_are_you. whether there’s a value for that element web pages with information from the da-
Some other arrays containing similar of the array. If there is, assume the form tabase. With recent versions of PHP, the
kinds of data are: has been submitted and go on to print easiest way to do this is with the PDO
out some data. If not, then display the extension, which provides a standard-
$_GET: query string variables form. In a real program, you’d probably ized access interface no matter which re-
$_COOKIE: U check the length of the string or its con- lational database you’re talking to. The
submitted cookie values tents here as well. only thing that changes is how you spec-
$_SERVER: assorted server-y U Fourth, it is incredibly easy to write in- ify what database you connect to and,
data such as the current URL, U secure PHP programs. The task that PHP potentially, any vendor-specific SQL you
current host name, U is usually put to involves web pages that want to use. Listing 2 is an extension of
values from HTTP request headers accept submitted data and then manipu- the Hello, World example above so that
$_ENV: environment variables late or display that submitted data. the entered names get saved in a data-
Another way of describing that task is base, and then a list of them is displayed
Security Matters “allow anybody in the world to throw after a name is entered.
arbitrary data into your application and Save this program as hello-db.php to
In practice, programs implement vary-
allow anybody in the world to view use it on your computer, or change the
ing degrees of authentication, access
control, data filtering, and data escap- whatever data you’ve got.” value of the action element of the form
ing. A huge portion of PHP security See the box titled “Security Matters” to whatever you save the program as.
problems are the result of an attack for more about security in PHP.
called cross-site scripting. Database Interaction
This attack boils down to allowing Evil Talking to a Database Aside from the additional check on the
Alice to upload some content to an inno- The most common use for PHP is stuff- length of the submitted name (using
cent (but poorly coded) website such ing information from a web form into a strlen()), all the new code in this exam-
that, when User Bob visits the site, the
content is sent to User Bob and then it
does something bad to Bob.
Listing 2: Hello, Database
There are intricacies to protecting 01 <?php 19 print "Hello, " .
against this sort of attack (and some 02 // Connect to the database htmlspecialchars($_POST['who_
further reading is listed at the end of are_you']) . '<br/>';
03 $dbh = new PDO('sqlite:/tmp/
the article) but the htmlspecialchars() 20
guestbook.db');
function, used in Listing 1, gets you
04 // Report errors if there are 21 // Get other entries from
most of the way. Apply this function to
database problems the database
any untrusted external data before you
include it in web-page output. The func- 05 $dbh->setAttribute(PDO::ATTR_ 22 print "Other entries:";
tion transforms characters that have ERRMODE, PDO::ERRMODE_ 23 print '<ul>';
special meaning in HTML to their HTML- WARNING); 24 foreach ($dbh->query('SELECT
entity equivalents; the characters it
06 * FROM article_name_test') as
transforms are &, ", <, and >. This means
that 07 // Make sure a name is $row) {
<?php submitted and it's not empty 25 printf("<li>%s on %s</
print htmlentitiesU 08 if (! (isset($_POST['who_are_ li>", $row['name'],
("<script>alert('hello!');U you']) && strlen($_POST['who_ 26 date('F j, Y',
</script>"); are_you']))) strtotime($row['inserted_
?> 09 { ?> on'])));
causes the following to be part of the 10 <form method="post" 27 }
web page output: action="hello-db.php"> 28 print '</ul>';
&lt;script&gt;alert('hello!');U
11 <p>What's your name?</p> 29
&lt;/script&gt;
12 <input type="text" name="who_ 30 // Insert the just-entered
Without the entity encoding, the
are_you" /> name into the database
browser would see <script>alert('hello!')
;</script> and treat the business inside 13 <br/> 31 $stmt =
the <script/> tag as JavaScript, popping 14 <input type="submit" $dbh->prepare('INSERT INTO
up a little alert dialog box. value="Go!" /> article_name_test
More malicious exploits, however, are (name,inserted_on) VALUES (?,
15 </form>
the norm. With the entity encoding, the ?)');
browser displays a < when it encounters 16
32 $stmt->execute(array($_
&lt; and a > when it encounters &gt;. 17 <?php } else { POST['who_are_you'],
This prevents malicious script code from
18 // Print out the date('c')));
running on unsuspecting User Bob’s
just-entered name 33 }
computer.

FEBRUARY 2008 ISSUE 87 23


COVER STORY PHP Scripting Intro

$row['inserted_on'] contains the value The table used in Listing 2 has the
Listing 3: XML Example
of the inserted_on column of the row. following structure:
Output PHP’s printf() function acts just like
01 MyCorgi.com: A Network for its C-library counterpart, and so it is a CREATE TABLE article_name_test (
Welsh Corgis & Their Owners tidy way to mix dynamic data into a name VARCHAR(255) NOT NULL,
02 interstate: For Skaters...By string. The strtotime() function turns inserted_on DATETIME NOT NULL
Skaters... the ISO datestamp that comes out of the )
03 You WILL Experience the Day of
database into a Unix Epoch timestamp,
the Ninja and the date() function uses the format You could create this table in the data-
string F j, Y to turn that timestamp into base with the following PHP program:
04 Ballroom Dance Channel Social
a string such as December 3, 2008.
05 You've Got to Hide Your Love
The last bit of code in the example in- <?php
Away
serts the newly submitted name into the
06 Loud Old Guys database table. $dbh = new PDOU
07 Meet Pete ('sqlite:/tmp/guestbook.db');
08 Duke City Fix: The Inside Line Prepared Statement $dbh->execU
on Albuquerque, NM The $dbh->prepare() function creates ('CREATE TABLE U
09 Mahalo Daily a prepared statement – a template of an article_name_test (
SQL statement that can be executed name VARCHAR(255) NOT NULL,
many times. In each execution, the ?s inserted_on DATETIME NOT NULL
ple has to do with database interaction. (called placeholders) in the prepared )');
The PDO object, created at the beginning statement are replaced by actual values.
of the example, provides access to the To execute a prepared statement, call ?>
database. Exactly which database it’s the execute() method on the statement
providing access to depends on the DSN object and pass it an array containing Processing XML
(Data Source Name) provided to the values to bind to each placeholder. Another popular PHP task is dealing
PDO constructor. Two very good reasons exist for using with XML. PHP 5 gives you two splendid
This example uses SQLite, a snappy prepared statements instead of building choices: SimpleXML module for basic
filesystem-based database that comes literal SQL queries as strings containing XML parsing, and the DOM module for
with PHP. SQLite is handy for many dynamic data: performance and security. Document Object Model API action.
tasks because it doesn’t require installa- With SimpleXML, an XML document
tion and tuning of separate software or Speed is represented as a PHP object:
monitoring of other processes. Depending on the database engine
The DSN in the example provides the you’re using, executing a prepared state- <?php
pathname (/tmp/guestbook.db) that ment a few times is faster than building $feed = simplexml_load_fileU
you'll use for the database. a new SQL query with the dynamic data ('http://blog.ning.com/U
After connecting to the database and directly inside it each time. With the pre- atom.xml');
creating a new PDO object, the code pared statement, the database engine
calls $dbh->setAttribute() to adjust can plan ahead and optimize the query. foreach U
PDO’s error-reporting mode. ($feed->entry as $entry) {
The PDO::ERRMODE_WARNING mode Security print $entry->title . "\n";
is useful for exploration and debugging The potential performance increase isn’t }
because it causes any database errors to such a big deal in this small example; ?>
be reported as part of PHP’s regular out- however, the security difference is. Pre-
put stream. pared statements protect you from SQL This PHP program prints something like
The rest of the database interaction in Injection attacks because they take care the output in Listing 3.
the example happens after a valid name of properly escaping the dynamic data. The simplexml_load_file() function,
is submitted. First, the $dbh->query() In the example, if the $_POST['who_are_ like most file-access functions in PHP,
method is used to retrieve some rows you'] variable contains characters that can accept URLs as well as local file
from the table. The method acts as an it- have special meaning in an SQL query, paths. With one step, the function loads
erator in PHP, so you can slap it directly such as ' (the string delimiter), PDO the Atom feed at http://blog.ning.com/
inside a foreach() loop, and the loop takes care of escaping them properly atom.xml into the $feed object.
variable ($row) is populated with each so they don’t cause any problems. Because the structure of an Atom feed
row from the result set. Without prepared statements, you means the root element has a number
By default, rows are represented as ar- would have to make sure you escape all of children named <entry/>, the entry
rays, so you can use the column names dynamic data going into a query; one property of the $feed object can be
for array keys to access the data – mistake and you open up your database treated as an array with foreach().
$row['name'] contains the value of the to all sorts of scurvy treachery or data Similarly, because each <entry/> has
name column of the row and leakage. a <title/> child, the value of the title

24 ISSUE 87 FEBRUARY 2008


PHP Scripting Intro COVER STORY

property of the $entry object is the text Although the syntax in Listing 4 is PECL [4] is the place to go for binary
content of that <title/> child. (Note PHP-specific, the classes and methods PHP extensions, such as modules for
that while the object properties, such as are all part of the language-neutral DOM embedding Lua in PHP programs, hook-
entry and title, explicitly correspond to API. A document is represented by a ing up with the ImageMagick library,
XML element names, there is no require- DOMDocument object, DOMDocument:: or implementing all sorts of other third-
ment that the PHP variable names be the createElement() creates elements that party integrations.
same as the XML element names – it is DOMDocument::appendChild() adds to Good places to look for libraries and
only for convenience that the example the document, and DOMElement::setAt- extensions written in PHP (so no messy
code uses PHP variable names such as tribute() adds an attribute to an element. compilation for installation) are the PHP
$feed and $entry.) The DOMDocument::saveXML() Application and Extension Repository
The SimpleXML module is super for method returns the XML representation (PEAR) [5], Zend Framework [6], and eZ
doing something with an Atom or RSS of the document. If you pass the method Components [7] sites.
feed, or other straightforward XML pro- a filename, it writes the XML to that file Some popular MVC-style web frame-
cessing tasks. instead. works for PHP are CakePHP [8], Sym-
For heavier XML lifting, PHP also sup- fony [9], and Solar [10].
ports the full DOM Level 3 API. Level 3 What Next?
DOM also can be a good choice for XML If you’re running Linux or Mac OS X, Conclusions
processing in PHP if you’re already fa- your computer probably already has As I’ve already mentioned, it is easy to
miliar with the DOM API from another PHP on it. Generally, Linux distributions write insecure programs in PHP. Don’t
language, such as JavaScript. are pretty good at bundling up-to-date add to the depressingly large amount of
Listing 4 uses the DOM API to build PHP versions. insecure PHP code.
a small XML document. Mac OS X is not as good – head over A good resource for learning about
The XML document that this example to entropy.ch to download Marc Li- more secure PHP programming is Essen-
prints looks like: yanage’s great OS X PHP packages. The tial PHP Security by Chris Shiflett [11]. If
main PHP distribution site has Windows you’re a server administrator, take a look
<?xml version="1.0"?> binaries as well as source code [1]. at Suhosin [12], which prevents assorted
<people> The PHP manual [2] is a fantastic re- malicious local and remote attacks. ■
<person flavor=U source, not only for the comprehensive
"chocolate">alice</person> function and class documentation, but INFO
<person flavor=U also for all the user-contributed com-
[1] PHP distribution site:
"vanilla">bob</person> ments. PHP Planet [3], which is an ag- http://www.php.net/downloads.php
<person flavor=U gregation of popular PHP-themed blogs,
[2] PHP manual: http://php.net/manual
"strawberry">charlie</person> is also a good place to keep up with
[3] PHP Planet: http://planet-php.net
</people> what’s going on in the PHP universe.
[4] PECL: http://pecl.php.net

Listing 4: Building a Doc with DOM [5] PHP Application and Extension
Repository (PEAR): http://pear.php.net
01 <?php person that
[6] Zend Framework:
02 17 // contains an attribute with
http://framework.zend.com
03 // Some data to use the flavor
[7] eZ Components:
04 $flavors = array('alice' => 18 foreach ($flavors as $who =>
http://ez.no/components
'chocolate', $what) {
[8] CakePHP: http://www.cakephp.org
05 'bob' => 19 $el =
'vanilla', $doc->createElement('person', [9] Symfony:
$who); http://www.symfony-project.org/
06 'charlie' =>
'strawberry'); 20 [10] Solar: http://solarphp.com/

07 $el->setAttribute('flavor', [11] Shiflett, Chris. Essential PHP


$what); Security. O’Reilly, 2005.
08 // Create a new document
21 $root->appendChild($el); [12] Suhosin: http://www.suhosin.org
09 $doc = new DOMDocument();
22 }
10
23 David Sklar is a software architect
11 // Create a root container
for Ning, Inc. He has written three
THE AUTHOR

element 24 // Ensure readable output


formatting books on PHP programming. Learn-
12 $root = $doc->createElement('p ing PHP 5 (O’Reilly) provides a gen-
eople'); 25 $doc->formatOutput = true;
tle introduction to PHP. PHP Cook-
13 // And add it to the document 26 // Display the XML book (O’Reilly), co-authored by
14 $doc->appendChild($root); 27 print $doc->saveXML(); Adam Trachtenberg, is a collection
of recipes for PHP tasks. Essential
15 28
PHP Tools (Apress) is a guide to PHP
16 // Add an element for each 29 ?> add-on modules and libraries.

FEBRUARY 2008 ISSUE 87 25

You might also like