Cover | Table of Contents | Colophon
for and foreach loops.http://www.php.net/downloads.php. The
installation process is identical to PHP 4; however, PHP 5 does have
some new configuration options. See Table C-1 in
Appendix C for a complete list.$name = 'Rasmus Lerdorf';
$db = mysql_connect( );
$result = mysql_query("SELECT email FROM users
WHERE name LIKE '$name'", $db);
$row = mysql_fetch_assoc($r);
$email = $row['email'];
function getEmail($name) {
$db = mysql_connect( );
$result = mysql_query("SELECT email FROM users
WHERE name LIKE '$name'", $db);
$row = mysql_fetch_assoc($r);
$email = $row['email'];
return $email
}
$email = getEmail('Rasmus Lerdorf');
getEmail( ) has many benefits, including
reducing the amount of code you need to write to fetch an email
address. However, it also lets you safely alter your database schema
because you only need to change the single query in
getEmail( ) instead of searching through every
line of every file, looking for places where you
SELECT data from the users
table.$zeev->setName( )
didn't affect $rasmus in the
earlier example.$rasmus = new Person;
$rasmus->setName('Rasmus Lerdorf');
$zeev = $rasmus;
$zeev->setName('Zeev Suraski');
print $rasmus->getName( );
Zeev Suraski
$zeev does change
$rasmus!Rasmus
Lerdorf because $zeev = $rasmus causes
PHP to make a copy of the original object and assign it to
$zeev.$zeev a
reference to $rasmus. Any changes made to
$zeev are actually made to
$rasmus.function editName($person, $name) {
$person->setName($name);
}
$rasmus = new Person;
$rasmus->setName('Rasmus Lerdorf');
setName($rasmus, 'Zeev Suraski');
print $rasmus->getName( );
Zeev Suraski
editName( )
don't alter variables outside of the function, and
to update the original object you need to return
the modified variable. That's what you need to do in
PHP 4.class keyword followed by the class name:class Person {
}
Person class. This is not a
very exciting class, because it lacks methods or properties.
Class names in PHP are case-insensitive,
so you cannot define both a Person and a
PERSON class.$rasmus = new Person;
get_class( ):$person = new Person;
print get_class($person)
Person
get_class( ) on an instance of the
Person class produced person.
PHP 5 returns the correct class name.class Person {
public $name;
}
public
property named name. When a property is public, it
can be read from and written to anywhere in the program:$rasmus = new Person; $rasmus->name = 'Rasmus Lerdorf';
var.
This syntax is deprecated in favor of public, but
for backward compatibility, var is still legal.
The behavior of a property declared using public
and var is identical.public properties. Doing so makes it
easy to violate encapsulation. Always use accessor methods instead.$rasmus = new Person; $rasmus->email = 'rasmus@php.net';
rasmus@php.net to the
email property of $rasmus. This
is valid, even though email was not mentioned in
the class definition.Book,
CD, DVD, etc. However, you need
to know that your application can find the name, price, and inventory
number of each object, regardless of its type.interface Sellable {
public function getName( );
public function getPrice( );
public function getID( );
}
class, an interface
uses the keyword interface.
Inside the interface, define your method prototypes, but
don't provide an implementation.Sellable. Any
class that's Sellable must
implement the three methods listed in the interface:
getName( ), getPrice( ), and
getID( ).class Book implements Sellable {
public function getName( ) { ... }
public function getPrice( ) { ... }
public function getID( ) { ... }
}
ListenablePerson to create an
Employee class, where an
Employee is a Person with a
salary.Employee
is a Person:class Person {
private $name;
public function setName($name) {
$this->name = $name;
}
public function getName( ) {
return $this->name;
}
}
class Employee extends Person {
private $salary;
public function setSalary($salary) {
$this->salary = $salary;
}
public function getSalary( ) {
return $this->salary;
}
}
$billg = new Employee;
$billg->setName('Bill Gates');
$billg->setSalary(865114); // Actual 2003 salary (excluding stock)
Employee class;
instantiates a new instance of Employee,
$billg; and sets his name and salary.extends keyword at the top of the class definition
indicates to PHP that this class should inherit all the properties
and methods of the parent class. This allows you to interact with a
child object in the same way as its parent because when PHP cannot
find a property or method in the child class, it searches the parent
class._
_construct( ) and _ _destruct( ), but
these are not the only special methods in PHP 5._ _construct( )
_ _destruct( )
_ _get( )
_ _set( )
_ _call( )
_ _toString( )
_ _clone( )
_ _).mysqli for short.mysqli
come from two places. The majority are from new features available in
MySQL 4.1. However, PHP 5 also allows
mysqli to add an object-oriented interface.mysqli:mysqli with your existing PHP projects:mysql functions.mysqli. On
the other hand, you'll have some work to do if you:mysql-based codemysqli. In particular, if
you use the MySQL library bundled with PHP 4, you now must download
and install a new version of MySQL.http://www.mysql.com/.
If you're using mysqli, be sure
to use a copy of MySQL 4.1.2 or greater, as earlier versions
won't work with PHP.mysqli extension with the
--with-mysqli flag
during the PHP configure process.mysql, you don't tell
PHP where MySQL is located by adding the path to the MySQL base
installation. Instead, PHP uses MySQL's new
mysql_config file.mysql and
mysqli for a MySQL installation in
/usr/local/mysql:// mysql --with-mysql=/usr/local/mysql // mysqli --with-mysqli=/usr/local/mysql/bin/mysql_config
mysqlmysqli is largely identical to the older
mysql extension. Except, of course, all the
function names begin with mysqli instead of
mysql:$db = mysqli_connect($server, $user, $password) or
die("Could not connect: " . mysqli_error( ));
mysqli_select_db($db, "users");
$result = mysqli_query($db, "SELECT username FROM users");
while ($row = mysqli_fetch_assoc($result)) {
print $row['username'] . "\n";
}
mysqli_free_result($result);
mysqli_close($db);
users table, makes a query, and then fetches each
row as an associative array. These functions all behave the same as
their mysql counterparts, except that the
mysqli functions require a database handle as
their first argument instead of optionally allowing one as the final
argument. Section 3.10 covers all
the API changes in detail.mysqli_fetch_array( ). When there are no
additional rows, it returns NULL. The original
extension returns false. This difference
won't affect code like that shown here, where it
only assigns the result to a variable, but if you use !=
= to do a strict check against false,
you must now check against NULL.mysqli. Given the same query of SELECT
username FROM users, these example functions all print the
same results:// Fetch numeric arrays:
while ($row = mysqli_fetch_row($result)) {
print $row[0] . "\n";
}
// Alternative syntax:
while ($row = mysqli_fetch_array($result, MYSQLI_NUM)) {
print $row[0] . "\n";
}
// Alternative associative array syntax:
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
print $row['username'] . "\n";
}
// Both numeric and associative:
while ($row = mysqli_fetch_array($result, MYSQLI_BOTH)) {
print $row[0] . "\n";
print $row['username'] . "\n";
}
// Fetch as "object"
while ($row = mysqli_fetch_object($result)) {
print $row->username . "\n";
}mysql
connection functions take five parameters:mysql_connect(server, username, password, new_link, client_flags)
mysql.default_host.mysql_connect('db.example.org:3307');
true forces PHP to always make another link to
MySQL.MYSQL_CLIENT_COMPRESS,
MYSQL_CLIENT_IGNORE_SPACE, and
MYSQL_CLIENT_INTERACTIVE. These tell MySQL to
compress the connection,
ignore spaces after functions, and
modify how it determines when to close the connection, respectively.mysqlimysqli
extension also allows you to manipulate the data using an
object-oriented interface. Everything that can be done using the
procedural interface is available this way. Here is the same sample
transaction from the last section translated into the OO style:$mysqli = new mysqli('db.example.org', 'web', 'xyz@123');
$mysqli->select_db('users');
$result = $mysqli->query("SELECT username FROM users");
while ($row = $result->fetch_assoc( )) {
print $row['username'] . "\n";
}
$result->close( );
mysqli method. Instead, the extension stores that
handle as part of the mysqli object.mysql
and use the default link option, you may find it easier to switch to
the OO syntax because it doesn't require you to
modify the argument list of every mysql function.mysqli_init( ) and
mysqli_real_connect( ):$mysqli = new mysqli( );
$mysqli->init( );
$mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 120);
$mysqli->options(MYSQLI_OPT_LOCAL_INFILE, false);
$mysqli->real_connect('db.example.com', 'web', 'xyz@123', 'users',
3306, NULL, MYSQLI_CLIENT_COMPRESS);
mysqli object does not automatically call
mysqli_init( ) in its constructor. This is still
your responsibility.mysqli
functions are object properties instead of methods, in particular,
mysqli_error( ), mysqli_errno(
), and mysqli_insert_id( ).
Here's an example using mysqli_insert_id(
):// place new e-mail address on list:
$email = 'rasmus@php.net';
$list = 'php-general';
// escape data
$email = $mysqli->real_escape_string($email);
$list = $mysqli->real_escape_string($list);
$mysqli = new mysqli($server, $user, $password);
$mysqli->query("INSERT INTO addresses VALUES(NULL, '$email')");
$id = $mysqli->insert_id; // no ( ) necessary!
$mysqli->query("INSERT INTO lists VALUES($id, '$list')");// User-entered data
$username = 'rasmus';
$password = 'z.8cMpdFbNAPw';
$zipcode = 94088;
// Escape data
$username = mysqli_real_escape_string($db, $username);
$password = mysqli_real_escape_string($db, $password);
$zipcode = intval($zipcode);
// Create SQL query
$sql = "INSERT INTO users VALUES ('$username', '$password', $zipcode)";
// Make SQL query
mysqli_query($db, $sql) or die('Error');programs table:mysql> DESCRIBE programs; +------------+-----------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+-----------------+------+-----+---------+----------------+ | id | int(5) unsigned | | PRI | NULL | auto_increment | | title | varchar(50) | | | | | | channel_id | int(5) unsigned | | | 0 | | +------------+-----------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec) mysql> SELECT * FROM programs; +----+-----------------+------------+ | id | title | channel_id | +----+-----------------+------------+ | 1 | Oprah | 60 | | 2 | Sex and the City| 201 | | 3 | The Sopranos | 201 | | 4 | Frontline | 13 | +----+-----------------+------------+ 4 rows in set (0.00 sec)
// Find the names and address of all people // who have an email address ending in "php.net". SELECT name, email FROM users WHERE email LIKE '%.php.net'; // Find the title of all TV programs that air on channel 13 SELECT title FROM programs, channels WHERE channel.name = 'HBO' AND program.channel_id = channel.id;
mysql> SHOW VARIABLES LIKE 'have_innodb'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | have_innodb | YES | +---------------+-------+
YES. By default, MySQL enables
InnoDB tables as of Version 4.0, so if this variable is set to
NO, you should rebuild MySQL and remove
the
--without-innodb flag from your configuration.TYPE = InnoDB to the end of the
CREATE statement. For example, to replicate the
programs table:CREATE TABLE programs (id int(5) unsigned AUTO_INCREMENT,
title VARCHAR(50) not null,
channel_id int(5) unsigned not null,
primary key(id))
TYPE = InnoDB;mysql_query(
) once for each query. This often happens when you need
distinct pieces of information from MySQL or when you want to create
a fresh set of tables.phpMyAdmin (http://www.phpmyadmin.net), and want the
ability to take a database dump and recreate the information.split on the
semicolon (;). For example, it's
perfectly valid to have a line like INSERT INTO users
VALUES('rasmus', 'pass;word');. Since
pass;word is inside single quotes, MySQL knows it
doesn't signal the end of a statement, but a simple
split isn't smart enough to
understand this. As a result, you're effectively
forced to write a MySQL parser in PHP.mysqli_multi_query( ) function for
these types of cases.$sql = "SELECT account_number, balance FROM bank_accounts
WHERE secret_code LIKE '$_GET[secret_code]'";
GRANT table to require SSL.http://www.openssl.org/.mysqli
extension has many benefits over the older extension, they come at a
cost. Depending upon your code, porting to the new extension can be a
surprisingly tiresome task. If you've used a
database abstraction layer—such as
PEAR DB, ADOdb, or MDB—this task is
simplified considerably. Even though you're only
switching from one version of MySQL to another, the new extension is
sufficiently different that quite a bit of work is necessary to make
the switch.mysqli for
your new projects, and that requires an upgrade to MySQL 4.1. Since
an out-of-the-box MySQL 4.1 is incompatible with
mysql, this presents a bit of a dilemma. You want
the benefits of mysqli without worrying about
legacy code.mysqli_multi_query( ) and ssl_set(
).mysql to mysqli
INSERTs and
SELECTs, with SQLite you can also use
transactions, query using subselects, define your own functions, and
invoke triggers.SELECTing data.
If your application does an initial (or
periodic) data INSERT and then reads many times
from the database, SQLite is an excellent choice. The PHP web site
uses SQLite to handle some forms of searches.GRANT
and REVOKE keywords are not implemented. This
means you cannot create a protected table that only certain users are
allowed to access. Instead, you must implement access control by
using the read and write permissions of your filesystem.$db = sqlite_open('/www/support/users.db');
sqlite_query($db, 'CREATE TABLE users(username VARCHAR(100),
password VARCHAR(100))');
users table stored in the database file located at
/www/support/users.db.
When
you try to open a database file that doesn't already
exist, SQLite automatically creates it for you; you
don't need to execute a special command to
initialize a new database.INTEGER, SQLite won't complain if
you then INSERT the string PHP
into that column. This feature (the SQLite manual declares this a
feature, not a bug) is unusual in a database, but PHP programmers
frequently use this to their advantage in their scripts, so
it's not a completely crazy idea. A
column's type matters only when SQLite sorts its
records (what comes first: 2 or 10?) and when you enforce
UNIQUEness (0 and 0.0 are different strings, but
the same integer).username and password. The
columns' fields are all declared as
VARCHARs because they're supposed
to hold text. Although it doesn't really matter what
type you declare your fields, it can be easier to remember what
they're supposed to hold if you give them explicit
types.INSERT and sqlite_db_query( ):$username = sqlite_escape_string($username);
$password = sqlite_escape_string($password);
sqlite_query($db, "INSERT INTO users VALUES ('$userna