This allows you to create a database object and pass it for use in the class easily.. Creating a File to Store Database Credentials To keep the database credentials separate from the re
Trang 1}
?>
■ Note That the Calendar class constructor accepts an optional $dbo argument that is passed in turn to the
DB_Connect constructor This allows you to create a database object and pass it for use in the class easily
Creating a File to Store Database Credentials
To keep the database credentials separate from the rest of the application for easy maintenance, you
want to use a configuration file Create a new file called db-cred.inc.php in the config folder
(/sys/config/db-cred.inc.php) Inside, create an array called $C (for constants), and store each piece of
data as a new key-value pair:
<?php
/*
* Create an empty array to store constants
*/
$C = array();
/*
* The database host URL
*/
$C['DB_HOST'] = 'localhost';
/*
* The database username
*/
$C['DB_USER'] = 'root';
/*
* The database password
*/
$C['DB_PASS'] = '';
/*
* The name of the database to work with
*/
$C['DB_NAME'] = 'php-jquery_example';
?>
Trang 2■ Note Initializing $C as an empty array is a safeguard against any tainted pieces of data being stored in $C and defined as constants This is a good habit, especially when dealing with sensitive data
Save this file If you’re not using XAMPP or if you’ve modified the default database credentials, you’ll need to substitute your own host, username, password, and database name in the code
Creating an Initialization File
At this point, your database credentials still aren’t stored as constants You’ll be using an initialization file to handle this
An initialization file collects data, loads files, and organizes information for an application In this example, it will load and define all necessary constants, create a database object, and set up an
automatic loading function for classes Other functionality will be added later on as it becomes
necessary
Create a file called init.inc.php, and place it in the core folder (/sys/core/init.inc.php) Inside,
add the following:
<?php
/*
* Include the necessary configuration info
*/
include_once ' /sys/config/db-cred.inc.php';
/*
* Define constants for configuration info
*/
foreach ( $C as $name => $val )
{
define($name, $val);
}
/*
* Create a PDO object
*/
$dsn = "mysql:host=" DB_HOST ";dbname=" DB_NAME;
$dbo = new PDO($dsn, DB_USER, DB_PASS);
/*
* Define the auto-load function for classes
*/
function autoload($class)
{
$filename = " /sys/class/class." $class ".inc.php";
if ( file_exists($filename) )
{
Trang 3include_once $filename;
}
}
?>
An automatic loading function is called when a script attempts to instantiate a class that hasn’t been loaded yet It’s a convenient way to easily load classes into a script on demand For more information on
automatic loading, visit http://php.net/autoload
Creating an Index File to Pull It All Together
To see everything in action, modify index.php in the public folder Inside, simply include the
initialization file and instantiate the Calendar class Next, check if the class loaded properly, and output
the object’s structure if so:
<?php
/*
* Include necessary files
*/
include_once ' /sys/core/init.inc.php';
/*
* Load the calendar for January
*/
$cal = new Calendar($dbo, "2010-01-01 12:00:00");
if ( is_object ($cal) )
{
echo "<pre>", var_dump($cal), "</pre>";
}
?>
Once you navigate to http://localhost/, the following message is output:
object(Calendar)#2 (6) {
["_useDate:private"]=>
NULL
["_m:private"]=>
NULL
Trang 4["_y:private"]=>
NULL
["_daysInMonth:private"]=>
NULL
["_startDay:private"]=>
NULL
["db:protected"]=>
object(PDO)#3 (0) {
}
}
Setting Basic Properties
With all that infrastructure taken care of, you can get back to finishing the Calendar class’s constructor
After checking the database object, the constructor needs to store several pieces of data about the month with which it will be building a calendar
First, it checks if a date was passed to the constructor; if so, that is stored in the $_useDate property;
otherwise, the current date is used
Next, the date is converted to a UNIX timestamp (the number of seconds since the Unix epoch; read
more about this at http://en.wikipedia.org/wiki/Unix_time) before the month and year are extracted and stored in $_m and $_y, respectively
Finally, $_m and $_y are used to determine how many days are in the month being used and which
day of the week the month starts on
The following bold code adds this functionality to the constructor:
<?php
class Calendar extends DB_Connect
{
private $_useDate;
private $_m;
private $_y;
private $_daysInMonth;
Trang 5private $_startDay;
public function construct($dbo=NULL, $useDate=NULL)
{
/*
* Call the parent constructor to check for
* a database object
*/
parent:: construct($dbo);
/*
* Gather and store data relevant to the month
*/
if ( isset($useDate) )
{
$this->_useDate = $useDate;
}
else
{
$this->_useDate = date('Y-m-d H:i:s');
}
/*
* Convert to a timestamp, then determine the month
* and year to use when building the calendar
*/
$ts = strtotime($this->_useDate);
$this->_m = date('m', $ts);
$this->_y = date('Y', $ts);
/*
* Determine how many days are in the month
*/
$this->_daysInMonth = cal_days_in_month(
CAL_GREGORIAN,
$this->_m,
$this->_y
);
/*
* Determine what weekday the month starts on
*/
$ts = mktime(0, 0, 0, $this->_m, 1, $this->_y);
$this->_startDay = date('w', $ts);
}
Trang 6}
?>
Now all the properties that were previously NULL will have values when you reload
http://localhost/:
object(Calendar)#2 (6) {
["_useDate:private"]=>
string(19) "2010-01-01 12:00:00"
["_m:private"]=>
string(2) "01"
["_y:private"]=>
string(4) "2010"
["_daysInMonth:private"]=>
int(31)
["_startDay:private"]=>
string(1) "5"
["db:protected"]=>
object(PDO)#3 (0) {
}
}
Loading Events Data
To load data about events, you need to create a new method to access the database and retrieve them Because event data will be accessed in two ways (the second of which will be addressed later in this chapter), the act of loading data will be kept generic for easy reuse
This method will be private and named _loadEventData() It accepts one optional parameter—the
ID of an event—and follows these steps to load events:
Trang 71 Create a basic SELECT query to load the available fields from the events table
2 Check if an ID was passed, and if so, add a WHERE clause to the query to return
only one event
3 Otherwise, do both of the following:
• Find midnight of the first day of the month and 11:59:59PM on the last day
of the month
• Add a WHERE BETWEEN clause to only load dates that fall within the current
month
4 Execute the query
5 Return an associative array of the results
All put together, this method looks like so:
<?php
class Calendar extends DB_Connect
{
private $_useDate;
private $_m;
private $_y;
private $_daysInMonth;
private $_startDay;
public function construct($dbo=NULL, $useDate=NULL) { }
/**
* Loads event(s) info into an array
*
* @param int $id an optional event ID to filter results
* @return array an array of events from the database
*/
private function _loadEventData($id=NULL)
{
$sql = "SELECT
`event_id`, `event_title`, `event_desc`,
`event_start`, `event_end`
FROM `events`";
/*
* If an event ID is supplied, add a WHERE clause
* so only that event is returned
*/
Trang 8if ( !empty($id) )
{
$sql = "WHERE `event_id`=:id LIMIT 1";
}
/*
* Otherwise, load all events for the month in use
*/
else
{
/*
* Find the first and last days of the month
*/
$start_ts = mktime(0, 0, 0, $this->_m, 1, $this->_y); $end_ts = mktime(23, 59, 59, $this->_m+1, 0, $this->_y); $start_date = date('Y-m-d H:i:s', $start_ts);
$end_date = date('Y-m-d H:i:s', $end_ts);
/*
* Filter events to only those happening in the
* currently selected month
*/
$sql = "WHERE `event_start`
BETWEEN '$start_date'
AND '$end_date'
ORDER BY `event_start`";
}
try
{
$stmt = $this->db->prepare($sql);
/*
* Bind the parameter if an ID was passed
*/
if ( !empty($id) )
{
$stmt->bindParam(":id", $id, PDO::PARAM_INT); }
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
return $results;
}
catch ( Exception $e )
{
die ( $e->getMessage() );
}
}
Trang 9}
?>
■ Note For the sake of brevity, nonreferenced methods are collapsed
This method returns an array that, when using the test entries you entered into the database
previously, looks like this:
Array
(
[0] => Array
(
[event_id] => 1
[event_title] => New Year's Day
[event_desc] => Happy New Year!
[event_start] => 2010-01-01 00:00:00
[event_end] => 2010-01-01 23:59:59
)
[1] => Array
(
[event_id] => 2
[event_title] => Last Day of January
[event_desc] => Last day of the month! Yay!
[event_start] => 2010-01-31 00:00:00
[event_end] => 2010-01-31 23:59:59
)
)
Creating an Array of Event Objects for Use in the Calendar
The raw output of _loadEventData() isn’t immediately usable in the calendar Because events need to be displayed on the proper day, the events retrieved from _loadEventData() need to be grouped by the day
on which they occur For easy reference, the event fields will be simplified as well
The end goal is an array of events that will use the day of the month as its index, containing each
event as an object The two test entries in your database should end up being stored like so when the
new method is complete:
Array
(
[1] => Array
(
[0] => Event Object
Trang 10(
[id] => 1
[title] => New Year's Day
[description] => Happy New Year!
[start] => 2010-01-01 00:00:00
[end] => 2010-01-01 23:59:59
)
)
[31] => Array
(
[0] => Event Object
(
[id] => 2
[title] => Last Day of January
[description] => Last day of the month! Yay!
[start] => 2010-01-31 00:00:00
[end] => 2010-01-31 23:59:59
)
)
)
Creating an Event Class
To accomplish this, you must first create a new class called Event in the class folder
(/sys/class/class.event.inc.php) It will have five public properties: $id, $title, $description, $start, and $end; and a constructor that will set each of those properties using the associative array returned by
the database query Create the file, and insert the following code inside it:
<?php
/**
* Stores event information
*
* PHP version 5
*
* LICENSE: This source file is subject to the MIT License, available
* at http://www.opensource.org/licenses/mit-license.html
*
* @author Jason Lengstorf <jason.lengstorf@ennuidesign.com>
* @copyright 2010 Ennui Design
* @license http://www.opensource.org/licenses/mit-license.html
*/
class Event
{
/**