Posts Tagged 'PHP&'

Nov

15

PHP & Regular Expressions

Posted by admin under resource, technology - No Comments

What is a Regular Expression?

What do you think it is that separates programs like BBEdit and notepad from the good old console-based text editors? Both support text input and let you save that text into a file, however modern text editors also support other functionality including find & replace tools, which makes editing a text file so much easier.

Regular expressions are similar to this functionality, only better. Think of a regular expression as an extremely advanced find & replace tool that saves us the pain of having to write custom data validation routines to check e-mail addresses, make sure phone numbers are in the correct format, etc.

One of the most common functions of any program is data validation, and PHP comes bundled with several text validation functions that allow us to match a string using regular expressions, making sure there’s a space in a particular spot, a question mark in another spot, etc.

What you may not know however, is that regular expressions are simple to implement, and once you’ve mastered a few regular expressions (which are specially formatted strings that we can use to tell the regular expression engine the portion of a string we want to match) you’ll be asking yourself why you left regular expressions in the corner for so long.

PHP has two sets of functions for dealing with the two types of regular expression patterns: Perl 5 compatible patterns, and Posix standard compatible patterns. In this article we will be looking at the ereg function and working with search expressions that conform to the Posix standard. Although they don’t offer as much power as Perl 5 patterns, they’re a great way to start learning regular expressions. If you’re interested in PHP’s support for Perl 5 compatible regular expressions, then see the PHP.net site for details on the preg set of PHP functions.
PHP has six functions that Why Use Regular Expressions?

If you’re constantly creating functions to validate or manipulate portions of a string, then you might be able to scrap all of these functions and use regular expressions instead. If you answer yes to any of the questions shown below, then you should definitely consider using regular expressions:

  • Are you writing custom functions to make sure form data contains valid information (such as an @ and a dot in an e-mail address)?
  • Do you write custom functions to loop through each character in a string and replace it if it matches a certain criteria (such as if it’s upper case, or if it’s a space)?

Besides being unfavored methods for string validation and manipulation, the two points shown above can also slow your program down if coded inefficiently. Would you rather use this code to validate an e-mail address:
<?php
function validateEmail($email)
{
$hasAtSymbol = strpos($email, “@”);
$hasDot = strpos($email, “.”);
if($hasAtSymbol && $hasDot)
return true;
else
return false;
}echo validateEmail(“mitchell@interspire.com”);
?>

… or this code:

<?php
function validateEmail($email)
{
return ereg(“^[a-zA-Z]+@[a-zA-Z]+.[a-zA-Z]+$”, $email);
}
echo validateEmail(“mitchell@interspire.com”);
?>

Sure, the first function looks easier and seems well structured, but wouldn’t it be easier if we could validate an e-mail address using the one-lined version of the validateEmail function shown above?

The second function shown above uses regular expressions only, and contains one call to the ereg function. The ereg function always returns only true or false, indicating whether its string argument matched the regular expression or not

Many programmers steer clear of regular expressions because they are (in

The Regular Expression Syntax

Before you can match a string to a regular expression, you have to <?php echo ereg(“^hello”, “hello world!”); ?>

Would return true, however

<?php echo ereg(“^hello”, “i say hello world”); ?>

would return false, because hello wasn’t at the beginning of the string.

End of string:
To search at the end of a string, use $. For example,

<?php echo ereg(“bye$”, “goodbye”); ?>

Would return true, however

<?php echo ereg(“bye$”, “goodbye my friend”); ?>

would return false, because bye wasn’t at the very end of the string.

Any single character:
To search for any character, use the dot. For example,

<?php echo ereg(“.”, “cat”); ?>

would return true, however

<?php echo ereg(“.”, “”); ?>

would return false, because our search string contains no characters. You can optionally tell the regular expression engine how many single characters it should match using curly braces. If I wanted a match on five characters only, then I would use ereg like this:

<?php echo ereg(“.{5}$”, “12345″); ?>

The code above tells the regular expression engine to return true if and only if at least five successive characters appear at the end of the string. We can also limit the number of characters that can appear in successive order:

<?php echo ereg(“a{1,3}$”, “aaa”); ?>

In the example above, we have told the regular expression engine that in order for our search string to match the expression, it should have between one and three ‘a’ characters at the end.

<?php echo ereg(“a{1,3}$”, “aaab”); ?>

The example above wouldn’t return true, because there are three ‘a’ characters in the search string, however they are not at the end of the string. If we took the end-of-string match $ out of the regular expression, then the string would match.

We can also tell the regular expression engine to match at least a certain amount of characters in a row, and more if they exist. We can do so like this:

<?php echo ereg(“a{3,}$”, “aaaa”); ?>

Repeat character zero or more times
To tell the regular expression engine that a character may exist, and can be repeated, we use the * character. Here are two examples that would return true:

<?php echo ereg(“t*”, “tom”); ?>
<?php echo ereg(“t*”, “fom”); ?>

Even though the second example doesn’t contain the ‘t’ character, it still returns true because the * indicates that the character may appear, and that it doesn’t have to. In fact, any normal string pattern would cause the second call to ereg above to return true, because the ‘t’ character is optional.

Repeat character one or more times
To tell the regular expression engine that a character must exist and that it can be repeated more than once, we use the + character, like this:

<?php echo ereg(“z+”, “i like the zoo”); ?>

The following example would also return true:

<?php echo ereg(“z+”, “i like the zzzzzzoo!”); ?>

Repeat character zero or one times
We can also tell the regular expression engine that a character must either exist just once, or not at all. We use the ? character to do so, like this:

<?php echo ereg(“c?”, “cats are fuzzy”); ?>

If we wanted to, we could even entirely remove the ‘c’ from the search string shown above, and this expression would still return true. The ‘?’ means that a ‘c’ may appear anywhere in the search string, but doesn’t have to.

The space character
To match the space character in a search string, we use the predefined Posix class, [[:space:]]. The square brackets indicate a related set of sequential characters, and “:space:” is the actual class to match (which, in this case, is any white space character). White spaces include the tab character, the new line character, and the space character. Alternatively, you could use one space character (” “) if the search string must contain just one space and not a tab or new line character. In most circumstances I prefer to use “:space:” because it signifies my intentions a bit better than a single space character, which can easy be overlooked. There are several Posix-standard predefined classes that we can match as part of a regular expression, including [:alnum:], [:digit:], [:lower:], etc. A complete list is available here.

We can match a single space character like this:

<?php echo ereg(“Mitchell[[:space:]]Harper”, “Mitchell Harper”); ?>

We could also tell the regular expression engine to match either no spaces or one space by using the ? character after the expression, like this:

<?php echo ereg(“Mitchell[[:space:]]?Harper”, “MitchellHarper”); ?>

Grouping patterns
Related patterns can be grouped together between square brackets. It’s really easy to specify that a lower case only or upper case only sequence of characters should exist as part of the search string using [a-z] and [A-Z], like this:

<?php
// Require all lower case characters from first to last
echo ereg(“^[a-z]+$”, “johndoe”); // Returns true
?>

or like this:

<?php
// Require all upper case characters from first to last
ereg(“^[A-Z]+$”, “JOHNDOE”); // Returns true
?>

We can also tell the regular expression engine that we expect either lower case or upper case characters. We do this by joining the [a-z] and [A-Z] patterns:

<?php echo ereg(“^[a-zA-Z]+$”, “JohnDoe”); ?>

In the example above, it would make sense if we could match “John Doe,” and not “JohnDoe.” We can use the following regular expression to do so:

^[a-zA-Z]+[[:space:]]{1}[a-zA-Z]+$

It’s just as easy to search for a numerical string of characters:

<?php echo ereg(“^[0-9]+$”, “12345″); ?>

Grouping terms
It’s not only search patterns that can be grouped together. We can also group related search terms together using parentheses:

<?php echo ereg(“^(John|Jane).+$”, “John Doe”); ?>

In the example above, we have a beginning of string character, followed by “John” or “Jane”, at least one other character, and then the end of string character. So …

<?php echo ereg(“^(John|Jane).+$”, “Jane Doe”); ?>

… would also match our search pattern.

Special character circumstances
Because several characters are used to actually specify the grouping or syntax of a search pattern, such as the parentheses in (John|Jane), we need a way to tell the regular expression engine to ignore these characters and to process them as if they were part of the string being searched and not part of the search expression. The method we use to do this is called “character escaping” and involves propending any “special symbols” with a backslash. So, for example, if I wanted to include the or symbol ‘|’ in my search, then I could do so like this:

<?php echo ereg(“^[a-zA-z]+|[a-zA-z]+$”, “John|Jane”); ?>

There are only a handful of symbols that you have to escape. You must escape ^, $, (, ), ., [, |, *, ?, +, and {.

Hopefully you've now gotten a bit of a feel for just how powerful regular expressions actually are. Let's now take a look at two examples of using regular expressions to validate a string of data.

Regular Expression Examples

Example One
Let's keep the first example fairly simple, and validate a standard URL. A standard URL (with no port number) consists of three parts:

[protocol]://[domain name]

Let’s start by matching the protocol part of the URL. Let’s make it so that only http or ftp can be used. We would use the following regular expression to do so:

^(http|ftp)

The ^ character specifies the beginning of the string, and by enclosing http and ftp in brackets and separating them with the or character (|), we are telling the regular expression engine that either the characters http or ftp must be at the beginning of the string.

A domain name usually consists of www.somesite.com, but can optionally be specified without the www part. To keep our example simple, we will only allow .com, .net, and .org domain names to be considered valid. We’d represent the search term for the domain name part of our regular expression like this:

(www.)?.+.(com|net|org)$

Putting everything together, our regular expression could be used to validate a domain name, like this:

<?php
function isValidDomain($domainName)
{
return ereg(“^(http|ftp)://(www.)?.+.(com|net|org)$”, $domainName);
}

//true
echo isValidDomain(“http://www.somesite.com”);

//true
echo isValidDomain(“ftp://somesite.com”);

//false
echo isValidDomain(“ftp://www.somesite.fr”);

//false
echo isValidDomain(“www.somesite.com”);
?>

Example Two
Because I reside in Sydney Australia, let’s validate a typical international Australian phone number. The format of an international Australian phone number looks like this:

+61x xxxx-xxxx

The first ‘x’ is the area code, and the rest is the phone number. To validate that the start of the phone number is ‘+61′ and that it is followed by an area code between two and nine, we use the following regular expression:

^+61[2-9][[:space:]]

Notice in the search pattern above that the ” escapes the ‘+’ symbol so that it is [0-9]{4}-[0-9]{4}$

Nothing out of the ordinary here, we’re just telling the regular expression engine that for the phone number to be valid, it must have a group of four digits, followed by a hyphen, followed by another group of four digits and then an end of string character.

Putting the entire regular expreesion together into a function, we can use the code to validate <?php
function isValidPhone($phoneNum)
{
echo ereg(“^+61[2-9][[:space:]][0-9]{4}-[0-9]{4}$”, $phoneNum);
}

// true
echo isValidPhone(“+619 0000-0000″);

// false
echo isValidPhone(“+61 00000000″);

// false
echo isValidPhone(“+611 00000000″);
?>

Conclusion

Regular expressions take a lot of the hassle out of writing lines and lines of repetitive code to validate a string. Over the last few pages we’ve covered all of the basics of Posix standard regular expression patterns including symbols, grouping and the PHP ereg function.
We’ve also seen how to use the regular expression engine to validate some simple strings in PHP.

Nov

15

Search Engine-Friendly URLs – PHP & MySQL Tutorials

Posted by admin under technology - No Comments

On today’s Internet, database driven or dynamic sites are very popular. Unfortunately the easiest way to pass information between your pages is with a query string. In case you don’t know what a query string is, it’s a string of information tacked onto the end of a URL after a question mark.

Read more:Search Engine-Friendly URLs [PHP & MySQL Tutorials]

Nov

15

PHP / Java Integration

Posted by admin under technology - No Comments

There are two possible ways to bridge PHP and Java: you can either integrate PHP into a Java Servlet environment, which is the more stable and efficient solution, or integrate Java support into PHP. The former is provided by a SAPI module that interfaces with the Servlet server, the latter by this Java extension.

The Java extension provides a simple and effective means for creating and invoking methods on Java objects from PHP. The JVM is created using JNI, and everything runs in-process.

….

Read more:http://nio.infor96.com/phpdoc-zh/ref.java.html

Nov

15

Using Perl code from PHP

Posted by admin under technology - No Comments

From: Zend

By Dmitry Stogov

April 14, 2004

Intended Audience
Introduction
Perl Interpreter in PHP
Using Perl Objects
Error Handling
Summary
About the Author

Intended Audience

This article describes the Perl extension for PHP. It is intended for developers who use both languages in their projects, or who are migrating from one language to the other. It could be of general interest to other developers.

Introduction

PHP and Perl are two very popular Web programming languages. They both have many libraries and extensions that can simplify the process of development, but often you can find a Perl library you want, and not the corresponding library in PHP. (Perl is older then PHP, so naturally it has a larger selection of libraries and extensions.) This was the main reason that the Perl extension for PHP was written.

Many large projects use both PHP and Perl, with some subsystems implemented in PHP, and others in Perl. Often these subsystems need to communicate with each other, and some Perl modules – such as PHP::Include and PHP::Session – have been implemented to achieve this (see http://www.cpan.org/modules/by-module/PHP/ for more information). However, although they allow PHP session files to be read, PHP variables to be serialized and simple PHP code to be executed from within Perl, there is no real communication between the two interpreters.

The PHP Perl extension was implemented to allow the usage of Perl code from within PHP. It is a wrapper that embeds the Perl interpreter and converts data from PHP to Perl and back. At the time of writing it only provides a one-way interface from PHP to Perl, but in the future it could be extended to implement a full two-way interface. The Perl extension allows the programmer to do the following from a PHP script:

  • load and execute Perl files
  • evaluate Perl code
  • access Perl variables
  • call Perl functions
  • instantiate Perl objects
  • access properties of Perl objects
  • call methods of Perl objects

All these features are accessible through a single API class called Perl.

PHP’s Perl extension is available from the PECL web site at http://pecl.php.net/package/perl. The latest development version can be obtained with the following CVS command:    $ cvs -d :pserver:cvs.php.net:/repository co pecl/perl

If you have a full Perl installation, the extension will work with it. If you don’t have Perl on board, you can still communicate with the Perl interpreter through PHP by putting a copy of perl58.so or perl58.dll somewhere PHP can find it (in the PHP directory or in your system path).

Perl Interpreter in PHP

To access the Perl interpreter from PHP, you must first create an instance of the Perl class. Its constructor can receive some parameters, but we will omit them at this point. They are necessary for working with Perl objects, but not for working with the interpreter itself.

    $perl = new Perl();

This line of code creates an instance of the Perl interpreter. It is possible to create several instances of the interpreter, but all of them will use the same one internally, so that all code and variables will be shared across instances. The object $perl can be used to execute external Perl files, evaluate inline Perl code, access Perl variables and call Perl functions.

External Perl files can be loaded using the Perl::require() method. Take a look at the following example:

Example 1 (test1.pl)

    print "Hello from Perl!\n"

Example 1 (test1.php)

    <?php

print "Hello from PHP!\n";
$perl = new Perl
();
$perl->require("test1.pl"
);
print
"Bye!\n"
;

?>

In this example Perl outputs a string directly to the PHP output stream, but in some cases you will want to grab the output as a string and process it with your PHP code. This can be done using the PHP output buffering API:

Example 2 (test2.php)

    <?php

ob_start();
$perl = new Perl
();
$perl->require("test1.pl"
);
$out =
ob_get_contents();
ob_end_clean();
print
"Perl: $out"
;

?>

As you can see, it works fine. Of course the same can be done with PHP’s system call, but less efficiently. The system() function will start the interpreter each time it’s called, whereas $perl->eval() uses the embedded interpreter in the same address space and doesn’t need to create a new process.

As was said earlier, the PHP Perl extension can evaluate inline Perl code. This method is more useful if you want to execute a small piece of code. With the Perl::eval() method you don’t need to create several small Perl files, but can instead simply embed Perl code into PHP.

Example 3 (test3.php)

    <?php

print "Hello from PHP!\n";
$perl = new Perl
();
$perl->eval('print "Hello from Perl!\n"'
);
print
"Bye!\n"
;

?>

Perl::eval() accepts only one argument – the Perl code to execute, in string format. PHP allows 3 different ways of writing string literals; single quoted, double quoted or heredoc. Note that PHP will act on the content of literal strings in the usual way before they are passed to Perl (see http://www.php.net/manual/language.types.string.php for details).

In the previous example we didn’t receive any unexpected results from Perl::eval(), but we could do so. The Perl interpreter can run the same code in different contexts, and the result can be very different in those different contexts. For example, a list returned in a scalar context would be received as the final element of that list.

A Perl class uses the scalar context by default, but evaluating in an array or hash context[1] requires the use of special tricks. The method eval() should not be called directly on the Perl interpreter object, but on the appropriate property (array or hash).

Example 4 (test4.php)

    <?php

$perl = new Perl();
var_dump($perl->eval('("a","b","c")'));        // eval in scalar context
var_dump($perl->array->eval('("a","b","c")')); // eval in array context
var_dump($perl->hash->eval('("a","b","c")'));  // eval in hash context

/* output:

string(1) "c"
array(3) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
string(1) "c"
}
array(2) {
["a"]=>
string(1) "b"
["c"]=>
NULL
}
*/

?>

This example evaluates the same data – a list – in different contexts, and as you can see, there are three different results from that data.

Perl has several scopes of global variables (scalars $x, arrays @x, hashes %x and code &x). PHP’s Perl extension allows you to access global scalar, array and hash variables. To access scalar Perl variables, just use the property with the same name. To access array and hash variables, use the same trick as for selecting the evaluation context.

Example 5 (test5.php)

    <?php

$perl = new Perl();
$perl->eval('$x = 1; @x  = 1..4; %x  = 1..4'
);
var_dump($perl->x);
var_dump($perl->array->x);
var_dump($perl->hash->x);

/* output:

int(1)
array(4) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
}
array(2) {
[1]=>
int(2)
[3]=>
int(4)
}
*/

?>

As you see, here we have three variables with the same name but in different scopes, and of course all three have different values.

The Perl extension allows not only reading but also writing to Perl variables. You can do this by assigning a new value to the corresponding property; however, you cannot modify part of a Perl array or hash. (The modification will not take effect.)

Evaluating Perl variables is just one simple interaction between PHP and Perl. More often we need to call a single Perl function. PHP’s Perl extension provides a simple and elegant way to do this. You just need to call the method with the corresponding name via the interpreter, and pass parameters to it:

Example 6 (test6.php)

    <?php

$perl = new Perl();
$perl->eval(
'
sub sum {
my $x = shift(@_);
foreach my $y (@_) {
$x += $y;
}
return $x;
}
'
);

print $perl->eval("sum(1, 2, 3, 4, 5, 6, 7, 8, 9)")."\n";
print
$perl->sum(1, 2, 3, 4, 5, 6, 7, 8, 9)."\n"
;

?>

The function can receive parameters and return a scalar or complex value. As with eval(), any function call can be made in one of three different contexts (scalar, array or hash), and the context can be specified in the same way.

Perl uses packages to limit the name scope of variables and functions, and sometimes we need to call functions or access variables from these packages using qualified names. Such names doesn’t confirm to PHP syntax, but they can be used with the special construct ->{}.

Example 7 (test7.php)

    <?php

$perl = new Perl();
$perl->eval('use Digest::MD5 qw(md5_hex);'
);

echo "PHP:\n";
var_dump(md5('Hello'));

echo "Perl:\n";
var_dump($perl->eval('md5_hex("Hello");'));
var_dump($perl->md5_hex("Hello"));
var_dump($perl->{"Digest::MD5::md5_hex"}("Hello"));

?>

This example uses the external Perl module md5, which is loaded during runtime. If you have a full Perl installation, downloading and installing CPAN modules is as easy as downloading a tarball, extracting it to the Perl top-level directory and typing:

    cd \perl
perl makefile.pl
make
make test
make install

at the command prompt. On Windows systems you will need to replace make with nmake; however, this will only work if you have MSVS tools installed.

If you don’t have a full Perl installation – i.e. you’re running Perl as a shared object – it is still possible to run Perl modules once they have been built elsewhere. The minimal environment necessary for running them consists of the entire set of Perl package management (*.pm) files from \perl\lib, and the full \perl\lib\auto and \perl\lib\Digest directories.

The PHP Perl extension cannot call internal Perl functions (print, read, etc); you will need to use Perl::eval() in order to access these. For example, in order to include the minimal module environment outlined above you would need to call:

    $perl->eval("BEGIN {unshift( @INC, 'perlenv_dirpath'); }");

Using Perl Objects

In common with many other programming languages, Perl uses an object-oriented approach, but it has no special syntax for classes. Classes are simply packages that happen to provide methods to deal with objects; methods are simply package functions that expect an object reference as the first argument; objects are simply references that ‘know’ which class they belong to.

The Perl extension allows you to instantiate Perl objects from a PHP script, and to access their properties and methods. The same Perl class is used for this, but this time you need to pass arguments to its constructor. The first argument is a Perl class (package) name, the second is the optional constructor name, and any remaining arguments are constructor-specific. If the constructor name is omitted then the default constructor new is used.

    new Perl(string class_name [, string constructor_name [, mixed args]]);The following example defines the Perl class Point with two constructors, new and Point. The first constructor doesn’t accept any special arguments; the second receives initial coordinate values. The class has two properties, x and y, and two methods, move() and get(). As you can see, the method move() moves a point to the offset specified in the arguments passed to it. The method get() is more interesting. Depending on the context, it returns the current coordinates as a string (in the scalar context) or as an array (in the array context).

As with native PHP objects, you can call the methods of instantiated Perl objects and access their properties. The only difference is the calling context. By default, methods are called in the scalar context. To call them in an array or hash context, use the same trick as before: the method should not be called directly on the Perl object, but on a special property (array or hash).

All properties can be accessed directly (without the array or hash property). This is because Perl objects can contain only scalar properties. Arrays and hashes are represented as references to them, and references are scalars in Perl. Object properties can be read, written, modified and even undefined, but parts of a property cannot be modified. For example, we can’t modify an element of an array property.

Example 8 (test8.php)

<?php

$perl = new Perl();
$perl->eval(
'
package Point;
sub new {
my $this = shift;
my $type = ref($this) || $this;
my $self = {};
$self->{x} = 0;
$self->{y} = 0;
bless $self, $type;
return $self;
}
sub Point {
my $this = shift;
my $type = ref($this) || $this;
my $self = {};
$self->{x} = shift;
$self->{y} = shift;
bless $self, $type;
return $self;
}
sub move {
my $self = shift;
$self->{x} += shift;
$self->{y} += shift;
}
sub get {
my $self = shift;
if (wantarray) {
return ($self->{x}, $self->{y});
} else {
return $self->{x} . "x" . $self->{y};
}
}
'
);

// create Perl object "Point" with constructor "new"
$p1 = new Perl("Point"
);
var_dump($p1);
$p1->x += 100;                     
// modify property
unset($p1->y);                     
// undefine property
var_dump($p1);

// create Perl object "Point" with constructor "Point"
$p2 = new Perl("Point", "Point", 100, 200
);
var_dump($p2);
$p2->move(200,200);                
// call method "move"
var_dump($p2->get());              // call method "get" in scalar context
var_dump($p2->array->get());       // call method "get" in array context
echo $p2->x . "." . $p2->y . "\n";
// print Perl object properties

?>

Error handling

The Perl extension uses the PHP exception mechanism to report Perl errors. A special exception class, PerlException, is used for this. The following example tries to evaluate invalid Perl code, and as a result Perl::eval() throws a PerlException:

Example 9 (test9.php)

    <?php

$perl = new Perl();
try {
var_dump($perl->eval('$a = $s{$d}.'));
echo
"ok\n"
;
}
catch (
PerlException $exception
) {
echo
"Perl error: " . $exception->getMessage() . "\n"
;
}

?>

Exceptions can be thrown by Perl::eval(), Perl::require(), or a call to a Perl function, object method or constructor.

Summary

The PHP Perl extension is a simple one-way binding from PHP to Perl. It allows you to execute Perl code from PHP, and has the ability to access Perl variables, call Perl functions, and instantiate Perl objects.

Note that the extension is still marked EXPERIMENTAL, so your ideas and suggestions can help to make it stable and usable. Please report any problems you find with the extension to http://bugs.php.net/.


[1] – Perl defines the scalar and array (list) contexts. The hash context is the same as the array (list) context, but the result is converted to an associative PHP array (hash array).

About the Author

Dmitry Stogov is the author of the PHP Perl extension. He also wrote the PHP SOAP extension and Turck MMCache. He currently resides in St.Petersburg, Russia with his wife and child.

Please feel free to post any comments or questions below, or send them to dmitry@zend.com.

Nov

15

Andreessen: PHP succeeding where Java isn’t

Posted by admin under technology - No Comments

By Stephen Shankland, CNET News.com
Published on ZDNet News: October 19, 2005, 5:00 PM PT

Forward in EMAIL Format for PRINT ZDNet Tags: Mobile platforms Java Web browsers Sun Microsystems Inc Microsoft Corp Intl Business Machines Corp
BURLINGAME, Calif.–The simplicity of scripting language PHP means it will be more popular than Java for building Web-based applications, Internet browser pioneer Marc Andreessen predicted Wednesday in a speech here at the Zend/PHP Conference.

Java enjoyed great success when its inventor, Sun Microsystems, released it in 1995, largely because it was optimized better for programmers than for machines, making software development significantly easier, Andreessen said. Unfortunately, Java has acquired many of the unfavorable characteristics of its predecessors, he added.

“Java is much more programmer-friendly than C or C++, or was for a few years there until they made just as complicated. It’s become arguably even harder to learn than C++,” Andreessen said. And the mantle of simplicity is being passed on: “PHP is such is an easier environment to develop in than Java.”

That opinion might not sit well with Java loyalists–and there are plenty of them among the millions of Java programmers and hundreds of companies involved in the Java Community Process that controls the software’s destiny.

But even some influential executives at IBM, which was instrumental in bringing Java to the server and whose WebSphere server software has Java at its core, see the benefits of PHP over Java.

“Simplicity is a huge part of it,” said Rod Smith, vice president of IBM’s Emerging Internet Technologies Group, describing PHP’s appeal to IBM in a meeting with reporters at the conference. “They weren’t interested in adding language features to compete with other languages,” choosing instead “the simple way, and not the way we’ve done it in Java, unfortunately.”

PHP is an open-source project including an engine to simple programs called PHP scripts and a large library of pre-built scripts. Much of its development is in the hands of a company called Zend, which sells packaged PHP products, programming tools and support.

Wooing programmers is nothing new in the computing industry, where players constantly jockey to establish their products as an essential foundation. Indeed, many credit Microsoft’s success to its highly regarded programming tools, which make it easier for developers to write software that run on Windows.

PHP has caught on widely. About 22 million Web sites employ it, and usage is steadily increasing. About 450 programmers have privileges to approve changes to the software. Major companies that employ PHP include Yahoo, Lufthansa and Deutsche Telekom’s T-Online.

PHP is more limited in scope than Java, which runs not just on Web servers but also on PCs, mobile phones, chip-enabled debit cards and many other devices. Some parts of the Java technology, though, such as Java Server Pages, handle much the same function.

“Java and PHP compete at some level. Get over it,” Mike Milinkovich, executive director of Eclipse, said in a meeting with reporters. Eclipse is an open-source programming-tool project that long supported Java and now also supports PHP. “I’m looking forward to PHP kicking butt in the marketplace,” Milinkovich said.

Java and PHP are drawing nearer to one another, though. Oracle, which also sells Java server software and whose database software can be used as a foundation for either Java or PHP, is among those working on an addition to Java to help the two software projects work together. Specifically, Java Specification Request 223 will “help build that bridge between the Java community and the PHP community,” said Ken Jacobs, vice president of product strategy at Oracle, in a speech at the conference.

And even Andreessen, who just helped launch a start-up called Ning for sharing photos, reviews or other content online, acknowledges that Java has its place.

“My new company is running a combination of Java and PHP. This is
something I get no end of crap about,” he said of the technical decision. “We have a core to our system that is built in Java. It is more like an operating system, like a system programming project. Then we have the entire application level–practically everything you see is in PHP.”

PHP, like open-source projects including Linux and Apache, now has received the blessing of major powers in the computing industry. IBM and Oracle are working on software that let PHP-powered applications pull information from their databases, and that endorsement has been important, said Zend CEO Doron Gerstel.

“The fact that IBM and Oracle are behind it–this is for a lot of IT (customers) a quality stamp. The big guys endorse it, so it must be good,” Gerstel said in a meeting with reporters.

The new version 5.1 of PHP, scheduled to arrive in early November, will include a faster engine to process PHP scripts, said Zeev Suraski, a Zend co-founder and PHP creator. It also will include a low-level “data abstraction layer” that makes it easier for PHP to communicate with different databases and a higher-level layer to interface with XML information produced and consumed by Web services.

Version 6, which is expected to arrive in 2006, will support Unicode character encoding, which supports a wide range of alphabets, simplifying creation of software that works in multiple international regions.

Andreessen said he believes the Web is where most new applications will reside–in part because Web applications are available as soon as they’re launched, sidestepping the distribution challenge of desktop software.

“Microsoft talks a lot about Avalon (display technology in the upcoming Vista version of Windows) and fat clients. But they still have a problem. You have to get the program out onto everybody’s desktop. With the Web model, you don’t,” Andreessen said. “I think there’s no question the Web model is going to dominate over the next 10, 20, 30 years.”

Some interesting work is being done on the PCs, however, but he pointed only to applications that run in a Web browser and that rely on data and services supplied over the Internet. Here, again, Java is losing to an unrelated scripting technology called JavaScript and a JavaScript offshoot called AJAX that permits a fancier user interface.

“JavaScript was, and now with AJAX is, the standard way to do client-side development in a browser, as opposed to Java,” Andreessen said. “Java applets in the browser never took to the extent some of us thought they would.”

Not everyone sees things the same way. Google uses some cutting-edge browser-based software such as AJAX, but CEO Eric Schmidt took the stage earlier this week with Sun CEO Scott McNealy to announce that the Google Toolbar will be piggybacking on distributions of the desktop version of Java.

“I was amazed to find out how much the Java Runtime Environment is inside companies, either because a CIO standardized on it or there are enough applications that the CIO wants the JRE to be a standard” part of the company’s computing infrastructure, Schmidt said at the Sun-Google event. As part of that partnership, Google will help develop Java.

Netscape pushed JavaScript as a way to build fancier Web pages than the fundamental HTML (Hypertext Markup Language) standard permitted, but without the more difficult programming Java required, Andreessen said. “We did JavaScript to try to be an intermediate bridge between HTML and Java. I got in huge fights with Sun over this,” Andreessen said. “They got mad. Then I told them we wanted to name it JavaScript, and that made them even madder.”

Java isn’t the only client software that didn’t live up to its promise, Andreessen said. Macromedia’s Flash format, which enables animation, sound, motion and other splashy features within browsers, also is on the list.

“I think Flash is one of the most exciting technologies out there that’s almost on the verge of great success and never quite achieving it,” Andreessen said.

Nov

15

SQLite My Fire! – SQLite in PHP 4 and PHP 5

Posted by admin under technology - No Comments

September 16, 2004

Hard Choices
Making New Friends
The Bookworm Turns
Anatomy Class
Different Strokes
Adding to the Collection
Not My Type
Starting From Scratch
A Few Extra Tools

Hard Choices
If you’ve been paying attention, you now know how to use PHP’s MySQL API to perform queries and process result sets. You might even have started thinking about how to re-program your site to run off a MySQL database. All of this is a Good Thing – it means you’re getting comfortable with using PHP’s database support to power your applications – but there’s still a little further to go.

As you saw in Part Eight, enabling MySQL support in PHP 5.0 is not as simple as it used to be. Instead of supporting MySQL out of the box, PHP now requires you to make all kinds of decisions about versions and libraries before allowing you to hook your scripts up to a MySQL database. If you’re lazy (and deep down, we both know you are), you might instead prefer to try a simpler option: the SQLite database engine.

Built-in SQLite support is new to PHP 5.0, and offers users a lightweight database system that is fast, efficient and gets the job done. Since it’s enabled by default in PHP 5.0, it provides a viable alternative to MySQL; you can use it out of the box, without spending time on version checks and library downloads; just install PHP 5 and start typing. That’s why I’m devoting a whole tutorial to it – so get out of bed, make yourself some coffee and let’s get started!

Making New Friends
Before getting into the code, let’s make sure that you have a clear idea of what SQLite is (and isn’t). Unlike MySQL, which operates on a client-server paradigm, SQLite is a file-based database engine and uses file I/O (input/output) functions to store and read databases from files on disk. It’s also much, much smaller than MySQL – the command-line version of SQLite weighs in at under 200 KB – and supports most of the SQL commands you’re used to.

This small size shouldn’t deceive you, however – according to the official SQLite Web site, SQLite supports databases up to 2 terabytes in size and is actually faster than MySQL in certain situations. SQLite database files are easily portable, and SQLite databases created on Windows work fine on *NIX platforms and vice-versa.

One of SQLite’s more interesting aspects is that it is completely typeless. Fields in an SQLite database need not be associated with a specific type, and even if they are, you can still insert values of different types into them (there is one exception to this rule, but I’ll get to that later). This is important, because it means that if you’re concerned about values of the wrong type getting into your tables, you need to write code to implement type checking in your application.

Another important difference between MySQL and SQLite lies in their licensing policies: unlike MySQL, SQLite source code is completely public-domain, which means that you can use and distribute it however you choose in both commercial and non-commercial products. Take a look at http://sqlite.org/copyright.html for more on this.

In order to use SQLite and PHP together, your PHP build must include SQLite. This is enabled by default in both the UNIX and Windows versions of PHP 5. Read more about this at http://www.php.net/manual/en/ref.sqlite.php. If you’re a PHP 4.x user, though, don’t lose heart – you can still use SQLite, by manually downloading and installing php_sqlite.dll from http://snaps.php.net (Windows) or the latest tarball from http://pecl.php.net/package/SQLite (UNIX). You don’t need to download anything else; the SQLite ‘client’ is its own engine.

The Bookworm Turns
As with MySQL, you use regular SQL commands to interact with an SQLite database. The exact SQL syntax used by SQLite is listed at http://sqlite.org/lang.html, but for most operations SQL commands are standard.

Here’s an example, which sets up the table I’ll be using in this tutorial:

C:\WINDOWS\Desktop\sqlite>sqlite library.db
SQLite version 2.8.15
Enter “.help” for instructions
sqlite> create table books (
…> id integer primary key,
…> title varchar(255) not null,
…> author varchar(255) not null
…>);
sqlite> insert into books (title, author) values (‘The Lord Of The Rings’, ‘J.R.R. Tolkien’);
sqlite> insert into books (title, author) values (‘The Murders In The Rue Morgue’, ‘Edgar Allen Poe’);
sqlite> insert into books (title, author) values (‘Three Men In A Boat’, ‘Jerome K. Jerome’);
sqlite> insert into books (title, author) values (‘A Study In Scarlet’, ‘Arthur Conan Doyle’);
sqlite> insert into books (title, author) values (‘Alice In Wonderland’, ‘Lewis Carroll’);
sqlite> .exit
You can enter these commands either interactively or non-interactively through the SQLite commandline program, which is available at http://sqlite.org/download.html as a precompiled binary for Windows and Linux. SQLite 2.* is the version currently used in both branches of PHP, with SQLite 3.* support anticipated for PDO and later PHP 5.* releases.

Extract the downloaded files to a directory of your choice, cd into it from your shell or DOS box and type ’sqlite’. You should see the SQLite version information and the line:

Enter “.help” for instructionsRead http://sqlite.org/sqlite.html for more information on how to use the commandline program.

Once the data has been imported into the database file library.db, run a quick SELECT query to check if everything is working as it should:

sqlite> select * from books;

1|The Lord Of The Rings|J.R.R. Tolkien
2|The Murders In The Rue Morgue|Edgar Allen Poe
3|Three Men In A Boat|Jerome K. Jerome
4|A Study In Scarlet|Arthur Conan Doyle
5|Alice In Wonderland|Lewis Carroll
If you saw the same output as above, you’re good to go!

Anatomy Class
Now, use PHP to communicate with SQLite, generate the same result set and format it as an HTML page. Here’s the code:

// set path of database file
$db = $_SERVER['DOCUMENT_ROOT'].”/../library.db”;

// open database file
$handle = sqlite_open($db) or die(“Could not open database”);

// generate query string
$query = “SELECT * FROM books”;

// execute query
$result = sqlite_query($handle, $query) or die(“Error in query: “.sqlite_error_string(sqlite_last_error($handle)));

// if rows exist
if (sqlite_num_rows($result) > 0) {
// get each row as an array
// print values
echo ”

“;
while($row = sqlite_fetch_array($result)) {
echo “”;
echo “”;
echo “”;
echo “”;
echo “”;
}
echo ”

“.$row[0].” “.$row[1].” “.$row[2].”

“;
}// all done
// close database file
sqlite_close($handle);
?>

If all goes well, you should see something like this:
If you remember what you learned in Part Eight, the PHP script above should be easy to decipher. In case you don’t, here’s a fast rundown:

The ball starts rolling with the sqlite_open() function, which accepts the name of the database file as argument and attempts to open it. If this database file cannot be found, an empty database file will be created with the supplied name (assuming the script has write access to the directory).
$db = $_SERVER['DOCUMENT_ROOT'].”/../library.db”;
$handle = sqlite_open($db) or die(“Could not open database”);

?>
The database file library.db needs to be kept somewhere it can’t be accessed through the browser by visitors to your site. That means that you need to create it outside your public_html, www or htdocs directory, in a directory that allows your scripts read/write permissions. Web hosting companies generally will offer a space above your web-visible directory where you can do this. $_SERVER['DOCUMENT_ROOT'].”/..” is the directory directly above your web-visible directory.

If successful, the sqlite_open() function returns a handle to the file, which is stored in the variable $handle and is used for all subsequent communication with the database.

The next step is to create and execute the query, with the sqlite_query() function.
$query = “SELECT * FROM books”;
$result = sqlite_query($handle, $query) or die(“Error in query: “.sqlite_error_string(sqlite_last_error($handle)));

?>
This function also needs two parameters: the database handle and the query string. Depending on whether or not the query was successful, the function returns true or false; in the event of a failure, the sqlite_error_string() and sqlite_last_error() functions can be used to display the error that took place.

If sqlite_query() is successful, the result set returned by the query is stored in the variable $result. You can retrieve the records in the result set with the sqlite_fetch_array() function, which fetches a single row of data as an array called $row. Fields in that record are represented as array elements, and can be accessed using standard index notation.
Each time you call sqlite_fetch_array(), the next record in the result set is returned. This makes sqlite_fetch_array() very suitable for use in a while() loop, in much the same way as mysql_fetch_row() was used earlier.

if (sqlite_num_rows($result) > 0) {
echo ”

“;
while($row = sqlite_fetch_array($result)) {
echo “”;
echo “”;
echo “”;
echo “”;
echo “”;
}
echo ”

“.$row[0].” “.$row[1].” “.$row[2].”

“;
}?>

The number of records returned by the query can be retrieved with the sqlite_num_rows() function. Or, if what you’re really interested in is the number of fields in the result set, use the sqlite_num_fields() function instead. Of course, these are only applicable with queries that actually return records; it doesn’t really make sense to use them with INSERT, UPDATE or DELETE queries.

Once you’re done, it’s a good idea to close the database handle and return the used memory to the system, with a call to sqlite_close():
sqlite_close($handle);

?>

In PHP 5 you can also use the SQLite API in an object-oriented way, wherein each of the functions above becomes a method of the SQLiteDatabase() object. Take a look at this next listing, which is equivalent to the one above:

// set path of database file
$file = $_SERVER['DOCUMENT_ROOT'].”/../library.db”;

// create database object
$db = new SQLiteDatabase($file) or die(“Could not open database”);

// generate query string
$query = “SELECT * FROM books”;

// execute query
// return result object
$result = $db->query($query) or die(“Error in query”);

// if rows exist
if ($result->numRows() > 0) {
// get each row as an array
// print values
echo ”

“;
while($row = $result->fetch()) {
echo “”;
echo “”;
echo “”;
echo “”;
echo “”;
}
echo ”

“.$row[0].” “.$row[1].” “.$row[2].”

“;
}// all done
// destroy database object
unset($db);
?>

Here, the new keyword is used to instantiate an object of the class SQLiteDatabase() by passing the object constructor the name of the database file. If the database file does not already exist, a new database file is created. The resulting object, stored in $db, then exposes methods and properties to perform queries. Every query returns an instance of the class SQLiteResult(), which in turn exposes methods for fetching and processing records.

If you look closely at the two scripts above, you’ll see the numerous similarities between the procedural function names and the object method names. While the correspondence between the two is not perfect, it’s usually close enough to make it possible to guess the one if you know the other.

Different Strokes
As with the MySQL API, PHP’s SQLite API offers you more than one way to skin a cat. For example, you can retrieve each row as an object with the sqlite_fetch_object() method, and access field values by using the field names as object properties. Here’s an example:

// set path of database file
$db = $_SERVER['DOCUMENT_ROOT'].”/../library.db”;

// open database file
$handle = sqlite_open($db) or die(“Could not open database”);

// generate query string
$query = “SELECT * FROM books”;

// execute query
$result = sqlite_query($handle, $query) or die(“Error in query: “.sqlite_error_string(sqlite_last_error($handle)));

// if rows exist
if (sqlite_num_rows($result) > 0) {
// get each row as an object
// print field values as object properties
echo ”

“;
while($obj = sqlite_fetch_object($result)) {
echo “”;
echo “”;
echo “”;
echo “”;
echo “”;
}
echo ”

“.$obj->id.” “.$obj->title.” “.$obj->author.”

“;
}// all done
// close database file
sqlite_close($handle);
?>

Another option is to retrieve the complete result set in one fell swoop with the sqlite_fetch_all() function. This function retrieves the complete set of records as an array of arrays; each element of the outer array represents a record, and is itself structured as an array whose elements represent fields in that record.

Here’s an example, which might make this clearer:

// set path of database file
$db = $_SERVER['DOCUMENT_ROOT'].”/../library.db”;

// open database file
$handle = sqlite_open($db) or die(“Could not open database”);

// generate query string
$query = “SELECT * FROM books”;

// execute query
$result = sqlite_query($handle, $query) or die(“Error in query: “.sqlite_error_string(sqlite_last_error($handle)));

// get the complete result set as a series of nested arrays
$data = sqlite_fetch_all($result);

// all done
// close database file
sqlite_close($handle);

// check the array to see if it contains at least one record
if (sizeof($data) > 0) {
echo ”

“;
// iterate over outer array (rows)
// print values for each element of inner array (columns)
foreach ($data as $row) {
echo “”;
echo “”;
echo “”;
echo “”;
echo “”;
}
echo ”

“.$row[0].” “.$row[1].” “.$row[2].”

“;
}
?>

In all the previous examples, the database remained open while the result set was processed, because records were retrieved one after another with the sqlite_fetch_array() or sqlite_fetch_object() functions. The example above is unique in that the database can be closed before the result set array is processed. This is because the entire result set is retrieved at once and stored in the $data array, so there really isn’t any need to leave the database open while processing it.

If your result set contains only a single field, use the sqlite_fetch_single()function, which retrieves the value of the first field of a row. The PHP manual puts it best when it says “this is the most optimal way to retrieve data when you are only interested in the values from a single column of data.” Take a look:

// set path of database file
$db = $_SERVER['DOCUMENT_ROOT'].”/../library.db”;

// open database file
$handle = sqlite_open($db) or die(“Could not open database”);

// generate query string
// this query returns only a single record with a single field
$query = “SELECT author FROM books WHERE title = ‘A Study In Scarlet’”;

// execute query
$result = sqlite_query($handle, $query) or die(“Error in query: “.sqlite_error_string(sqlite_last_error($handle)));

// if a row exists
if (sqlite_num_rows($result) > 0) {
// get the value of the first field of the first row
echo sqlite_fetch_single($result);
}

// all done
// close database file
sqlite_close($handle);
?>

You can even use the sqlite_fetch_single() function in combination with a while() loop to iterate over a result set containing many records but a single field. Notice also my usage of the sqlite_has_more() function, to check if the next row exists or not.

// set path of database file
$db = $_SERVER['DOCUMENT_ROOT'].”/../library.db”;

// open database file
$handle = sqlite_open($db) or die(“Could not open database”);

// generate query string
$query = “SELECT DISTINCT author FROM books”;

// execute query
$result = sqlite_query($handle, $query) or die(“Error in query: “.sqlite_error_string(sqlite_last_error($handle)));

// if rows exist
if (sqlite_num_rows($result) > 0) {
echo ”

“;
// check for more rows
while (sqlite_has_more($result)) {
// get first field from each row
// print values
$row = sqlite_fetch_single($result);
echo “”;
echo “”;
echo “”;
}
echo ”

“.$row.”

“;
}// all done
// close database file
sqlite_close($handle);
?>

You can, of course, do the same thing using object notation in PHP 5. However, you need to know that sqlite_has_more() is one function that really doesn’t translate to its object method name; in an OO script, you would need to call $result->valid();.

This script is the OO equivalent of the one above:

// set path of database file
$file = $_SERVER['DOCUMENT_ROOT'].”/../library.db”;

// create database object
$db = new SQLiteDatabase($file) or die(“Could not open database”);

// generate query string
$query = “SELECT DISTINCT author FROM books”;

// execute query
$result = $db->query($query) or die(“Error in query”);

// if rows exist
if ($result->numRows() > 0) {
echo ”

“;
// check for more rows
while ($result->valid()) {
// get first field from each row
// print values
$row = $result->fetchSingle();
echo “”;
echo “”;
echo “”;
}
echo ”

“.$row.”

“;
}// all done
// destroy database object
unset($db);
?>

Adding to the Collection
You can also use the sqlite_query() function (or the query() method) to perform INSERT, UPDATE and DELETE queries. The next example demonstrates, by allowing you to add new records to the books table through a form. Remember that your PHP script (or the user it’s running as) must have write privileges on the database file for this to work:

// set path of database file
$db = $_SERVER['DOCUMENT_ROOT'].”/../library.db”;

// open database file
$handle = sqlite_open($db) or die(“Could not open database”);

// check to see if the form was submitted with a new record
if (isset($_POST['submit'])) {
// make sure both title and author are present
if (!empty($_POST['title']) && !empty($_POST['author'])) {
// generate INSERT query
$insQuery = “INSERT INTO books (title, author) VALUES (\”".sqlite_escape_string($_POST['title']).”\”, \”".sqlite_escape_string($_POST['author']).”\”)”;
// execute query
$insResult = sqlite_query($handle, $insQuery) or die(“Error in query: “.sqlite_error_string(sqlite_last_error($handle)));
// print success message
echo “Record successfully inserted!

“;
}
else {
// missing data
// display error message
echo “Incomplete form input. Record not inserted!

“;
}
}

// now display all the records in the database
// generate SELECT query string
$query = “SELECT * FROM books”;

// execute query
$result = sqlite_query($handle, $query) or die(“Error in query: “.sqlite_error_string(sqlite_last_error($handle)));

// if rows exist
if (sqlite_num_rows($result) > 0) {
// get each row as an array
// print values
echo ”

“;
while($row = sqlite_fetch_array($result)) {
echo “”;
echo “”;
echo “”;
echo “”;
echo “”;
}
echo ”

“.$row[0].” “.$row[1].” “.$row[2].”

“;
}// all done
// close database file
sqlite_close($handle);
?>

Enter new record:

Book title:

Author:

Here’s what the initial form looks like:
And here’s what happens after you submit a record:

Notice my usage of the sqlite_escape_string() function on each INSERTed value – this takes care of escaping special characters in the user’s input, which could otherwise cause the update to fail.

Not My Type
Whilst on the topic of INSERT, remember my statement a couple pages back about how SQLite is typeless and so you can insert values of any type into any field? There is one important exception to this rule: a field marked as INTEGER PRIMARY KEY. In SQLite, fields marked as INTEGER PRIMARY KEY do two important things: they provide a unique numeric identifier for each record in the table, and if you insert a NULL value into them, SQLite automatically inserts a value that is 1 greater than the largest value already present in that field.

INTEGER PRIMARY KEY fields in SQLite thus perform the equivalent of AUTO_INCREMENT fields in MySQL, and are a convenient way of automatically numbering your records. Obviously, you can’t insert non-numeric values into such a field, which is why I said they were an exception to the typeless rule. Read more about this at http://www.sqlite.org/datatypes.html.

Since the books table used in the previous example already contains such a field (the id field), it’s clear that every INSERT into it with a NULL value for that field generates a new record number. If you’d like to retrieve this number, PHP has a way to do that too – just use the sqlite_last_insert_rowid() function, which returns the ID of the last inserted row (equivalent to the mysql_insert_id() function in PHP’s MySQL API).

To see this in action, update the if() loop in the middle of the previous script to include a call to sqlite_last_insert_rowid(), as follows:

// check to see if the form was submitted with a new record
if (isset($_POST['submit'])) {
// make sure both title and author are present
if (!empty($_POST['title']) && !empty($_POST['author'])) {
// generate INSERT query
$insQuery = “INSERT INTO books (title, author) VALUES (\”".sqlite_escape_string($_POST['title']).”\”, \”".sqlite_escape_string($_POST['author']).”\”)”;
// execute query
$insResult = sqlite_query($handle, $insQuery) or die(“Error in query: “.sqlite_error_string(sqlite_last_error($handle)));
// print success message
echo “Record successfully inserted with ID “.sqlite_last_insert_rowid($handle).”!

“;
}
else {
// missing data
// display error message
echo “Incomplete form input. Record not inserted!

“;
}
}

?>

If you need to, you can also find out how many rows were affected using the sqlite_changes() function – try it for yourself and see!

Starting From Scratch
You’ll remember, from the beginning of this tutorial, that I suggested you initialize the library.db database using the SQLite commandline program. Well, that isn’t the only way to create a fresh SQLite database – you can use PHP itself to do this, by issuing the necessary CREATE TABLE and INSERT commands through the sqlite_query() function. Here’s how:

// set path of database file
$db = $_SERVER['DOCUMENT_ROOT'].”/../library2.db”;

// open database file
$handle = sqlite_open($db) or die(“Could not open database”);

// create database
sqlite_query($handle, “CREATE TABLE books (id INTEGER PRIMARY KEY, title VARCHAR(255) NOT NULL, author VARCHAR(255) NOT NULL)”) or die(“Error in query: “.sqlite_error_string(sqlite_last_error($handle)));

// insert records
sqlite_query($handle, “INSERT INTO books (title, author) VALUES (‘The Lord Of The Rings’, ‘J.R.R. Tolkien’)”) or die(“Error in query: “.sqlite_error_string(sqlite_last_error($handle)));

sqlite_query($handle, “INSERT INTO books (title, author) VALUES (‘The Murders In The Rue Morgue’, ‘Edgar Allan Poe’)”) or die(“Error in query: “.sqlite_error_string(sqlite_last_error($handle)));

sqlite_query($handle, “INSERT INTO books (title, author) VALUES (‘Three Men In A Boat’, ‘Jerome K. Jerome’)”) or die(“Error in query: “.sqlite_error_string(sqlite_last_error($handle)));

sqlite_query($handle, “INSERT INTO books (title, author) VALUES (‘A Study In Scarlet’, ‘Arthur Conan Doyle’)”) or die(“Error in query: “.sqlite_error_string(sqlite_last_error($handle)));

sqlite_query($handle, “INSERT INTO books (title, author) VALUES (‘Alice In Wonderland’, ‘Lewis Carroll’)”) or die(“Error in query: “.sqlite_error_string(sqlite_last_error($handle)));

// print success message
echo “Database successfully initialized!”;

// all done
// close database file
sqlite_close($handle);

?>

Or, in PHP 5, you can use the object-oriented approach:

// set path of database file
$file = $_SERVER['DOCUMENT_ROOT'].”/../library3.db”;

// create database object
$db = new SQLiteDatabase($file) or die(“Could not open database”);

// create database
$db->query(“CREATE TABLE books (id INTEGER PRIMARY KEY, title VARCHAR(255) NOT NULL, author VARCHAR(255) NOT NULL)”) or die(“Error in query”);

// insert records
$db->query(“INSERT INTO books (title, author) VALUES (‘The Lord Of The Rings’, ‘J.R.R. Tolkien’)”) or die(“Error in query”);

$db->query(“INSERT INTO books (title, author) VALUES (‘The Murders In The Rue Morgue’, ‘Edgar Allan Poe’)”) or die(“Error in query”);

$db->query(“INSERT INTO books (title, author) VALUES (‘Three Men In A Boat’, ‘Jerome K. Jerome’)”) or die(“Error in query”);

$db->query(“INSERT INTO books (title, author) VALUES (‘A Study In Scarlet’, ‘Arthur Conan Doyle’)”) or die(“Error in query”);

$db->query(“INSERT INTO books (title, author) VALUES (‘Alice In Wonderland’, ‘Lewis Carroll’)”) or die(“Error in query”);

// print success message
echo “Database successfully initialized!”;

// all done
// destroy database object
unset($db);

?>

A Few Extra Tools
Finally, the SQLite API also includes some ancillary functions, to provide you with information on the SQLite version and encoding, and on the error code and message generated by the last failed operation. The following example demonstrates the sqlite_libversion() and sqlite_libencoding() functions, which return the version number and encoding of the linked SQLite library respectively:

// version
echo “SQLite version: “.sqlite_libversion().”
“;
// encoding
echo “SQLite encoding: “.sqlite_libencoding().”
“;

?>

When things go wrong, reach for the sqlite_last_error() function, which returns the last error code returned by SQLite. Of course, this error code – a numeric value – is not very useful in itself; to convert it to a human-readable message, couple it with the sqlite_error_string() function. Consider the following example, which illustrates by attempting to run a query with a deliberate error in it:

// set path of database file
$db = $_SERVER['DOCUMENT_ROOT'].”/../library.db”;

// open database file
$handle = sqlite_open($db) or die(“Could not open database”);

// generate query string
// query contains a deliberate error
$query = “DELETE books WHERE id = 1″;

// execute query
$result = sqlite_query($handle, $query) or die(“Error in query: “.sqlite_error_string(sqlite_last_error($handle)));

// all done
// close database file
sqlite_close($handle);

?>

Here’s what the output looks like:


Note that although they might appear similar, the sqlite_last_error() and sqlite_error_string() functions don’t work in exactly the same way as the mysql_errno() and mysql_error() functions. The mysql_errno() and mysql_error() functions can be used independently of each other to retrieve the last error code and message respectively, but the sqlite_error_string() is dependent on the error code returned by sqlite_last_error().

If your appetite has been whetted, you can read more about the things PHP can do with SQLite in Zend’s PHP 5 In Depth section.
And that’s about all I have for you in this tutorial. More secrets await you in Part 10 of PHP 101, so make sure you come back for that one!