BM Rational Build Forge started out as a small start-up company offering process automation software, most commonly used for automating software builds. As its customer base grew, its user interface made the change from a relatively simple PHP 4 web application to the Ajax-driven PHP 5 web application used today. During the migration to PHP 5 and a redesigned interface, IBM acquired the Austin-based company and introduced its own requirements and software standards.
In the journey to internationalization, scalability, performance tuning, and platform/database independence, the user interface used more and more of the language features and built-in functionality offered by PHP 5. The web application contains real world examples of how to use design patterns, class inheritance, interfaces, and Iterators in order to accelerate development while keeping functionality as reliable, maintainable, and fast as possible. This talk will explore how IBM Rational Build Forge uses PHP, looking at specific uses in the product today and coming in version 7.1.
1. Digging Through the Guts of Enterprise PHP 9/19/08 10:58 AM
1. Digging Through the Guts of Enterprise PHP
A Case Study
Shawn Lauriat
IBM Rational Build Forge
2. Introductions
Me
Advisory Engineer, Lead UI/G11N Developer @ IBM Rational Build Forge
Author, Advanced Ajax: Architectures and Best Practices
http://frozen-o.com/blog/
Build Forge
quot;It automates and accelerates build and release processes through server pooling and fault
tolerance for Agile development and streamlined software delivery.quot;
a.k.a. process automation tool
3. Disclaimer
The views expressed in this commentary are the author's own and do not necessarily reflect those of
IBM.
4. Overview
I will not:
Teach you to use PHP5 features
I will:
Show PHP5 features' usefulness
Show PHP5 features in code
Show PHP5 features in action
5. Interfaces
http://localhost/enterpriseguts/ Page 1 of 6
2. Digging Through the Guts of Enterprise PHP 9/19/08 10:58 AM
class -> Instance Definition
interface -> Instance Requirements Definition
interface + type hinting
= more stable code with less effort
6. BuildForge_Services_Serializable
/** Used for object transportation */
interface BuildForge_Services_Serializable {
/** @param array|null $data */
public function fromArray(array $data = null);
/** @return array */
public function toArray();
}
7. BuildForge_Services_DBO_Snapshottable
/** Create snapshot metadata */
$snapshot = BuildForge_Services_DBO_Snapshot::createSnapshot(
$services,
quot;My New Snapshotquot;,
quot;A Comment about My New Snapshotquot;
);
/** Get a new snapshot of the $originalOne */
return $originalOne->snapshot(
$snapshot->getUuid(),
new BuildForge_Services_DBO_SnapshotRequest(true),
false
);
8. Inheritance
BuildForge_Services_DBO_Project
http://localhost/enterpriseguts/ Page 2 of 6
3. Digging Through the Guts of Enterprise PHP 9/19/08 10:58 AM
Fields
Custom Methods
implements BuildForge_Services_DBO_Snapshottable
extends BuildForge_Services_UUIDDBO
::getUuid()
::isLive()
extends BuildForge_Services_DBO
implements BuildForge_Services_Serializable
::__construct()
9. Iterators
interface Iterator extends Traversable {
function rewind();
function current();
function key();
function next();
function valid();
}
10. Using Iterators for scalability
The Class Tree
Iterator
OuterIterator
BuildForge_Services_Iterator
BuildForge_Services_ProjectIterator
Iterator
BuildForge_Services_ValueIterator
11. Using Iterators for Scalability
The Code
http://localhost/enterpriseguts/ Page 3 of 6
4. Digging Through the Guts of Enterprise PHP 9/19/08 10:58 AM
class BuildForge_Services_DBO_ProjectIterator
extends BuildForge_Services_Iterator {
public function current() {
$current = parent::current();
if (empty($current)) return $current;
$project = new BuildForge_Services_DBO_Project($this->conn);
$project->fromArray($current);
return $project;
}
}
// Elsewhere in the app...
$projects = BuildForge_Services_DBO_Project::iterateAll($services);
foreach ($projects as $project) {
// Do stuff
}
12. Design Patterns
13. Model-View-Controller Code
class Projects {
public function render() {
$projects = BuildForge_Services_DBO_Project
http://localhost/enterpriseguts/ Page 4 of 6
5. Digging Through the Guts of Enterprise PHP 9/19/08 10:58 AM
::iterateFiltered(
$this->services,
$filter
);
$this->view->register_object('listing', $projects);
}
}
<tbody id=quot;listingquot;>
<?php try {
foreach ($_['listing'] as $project_instance) {
print '<tr>';
// etc.
print '</tr>';
}
} catch (Exception $e) { /* do something */ } ?>
</tbody>
14. Observer to Track State
class BuildForge_ServicesConnection
implements BuildForge_Strings_Localizer {
protected function createResponse() {
$this->mode = BUILDFORGE_SERVICES_MODE_READ;
$response = new BuildForge_Services_JSONResponse($this);
$response->attach($this);
return $response;
}
public function update(SplSubject $subject) {
$this->mode = BUILDFORGE_SERVICES_MODE_IDLE;
}
}
15. Observer to Track State
class BuildForge_Services_Response
extends BuildForge_Utilities_Observable {
public function __destruct() {
$this->readRemaining();
$this->notify();
}
}
http://localhost/enterpriseguts/ Page 5 of 6
6. Digging Through the Guts of Enterprise PHP 9/19/08 10:58 AM
16. Other PHP-Specific Additions
__toString() for all DBOs
print $project;
/* prints: Project[projectId=5bd405d70c3f1000d081238b009625ac, level=6, name=Project One, class=58BB01F0-836A-11DD-A3D4-
8B1B7F9F254D, selectorId=5bd403da0c3f100086e8238b0043b5da, tag=BUILD_$B, envId=, active=1, snotify=0, pnotify=0, fnotify=0,
maxThread=0, runLimit=0, tagSync=, sticky=, passChainId=, failChainId=, geoId=, isDefaultSnapshot=1, snapshotUuid=!Snapshot,
snapshotSetUuid=5bd405d30c3f1000d080238b009625ac, parentUuid=, steps= <Step[stepUuid=5bd405de0c3f1000d082238b009625ac,
projectId=5bd405d70c3f1000d081238b009625ac, stepId=1, envId=, filterId=, inlineChainId=, description=Step one, stepType=REGULAR,
dir=/, passNotify=0, failNotify=0, onFail=HALT, selectorId=, threaded=NO, absolute=, timeout=300, maxIterations=100, level=0,
broadcast=, commandText=echo quot;hiquot;, elseCommandText=, conditionText=, passChainId=, failChainId=, elseInlineId=, active=1, passWait=,
failWait=]>] */
__clone() for clone keyword support
$projectTwo = clone $projectOne;
$projectTwo->setName('Look, a new Project!');
$projectTwo->create();
17. These make my life easier
Object-Oriented
Inheritance
Interfaces
Type hinting
Exceptions
Iterators
18. What I can't wait to use next
Namespaces
Unicode
Late Static Bindings
Closures
try { } catch { } finally { } (Please?)
19. Questions?
http://localhost/enterpriseguts/ Page 6 of 6