php without php—confoo

110
PHP without PHP The Philosophy of Good Architecture terry chay 2010-03-10T09:30+0500 Confoo Montreal, Canada Thursday, March 18, 2010 An obscure but ubiquitous design pattern in PHP development is known as Funky Caching. Using real architectural examples as a lens to look at this one simple PHP design pattern, we see how we can design web architectures that are "organic, democratic, and lasting…"

Upload: terry-chay

Post on 24-May-2015

7.723 views

Category:

Technology


1 download

DESCRIPTION

An obscure but ubiquitous design pattern in PHP development is known as Funky Caching. Using real architectural examples as a lens to look at this one simple PHP design pattern, we see how we can design web architectures that are "organic, democratic, and lasting/"

TRANSCRIPT

Page 1: PHP Without PHP—Confoo

PHP without PHPThe Philosophy of

Good Architectureterry chay

2010-03-10T09:30+0500Confoo

Montreal, Canada

Thursday, March 18, 2010An obscure but ubiquitous design pattern in PHP development is known as Funky Caching. Using real architectural examples as a lens to look at this one simple PHP design pattern, we see how we can design web architectures that are "organic, democratic, and lasting…"

Page 2: PHP Without PHP—Confoo

Funky CachingPrologue #1

Thursday, March 18, 2010

Two prologues

Page 3: PHP Without PHP—Confoo

aka

Thursday, March 18, 2010

Often attributed to Rasmus, but actually invented by Stig First you create an ErrorDocument line in your apache.conf. What this does is tell the webserver to redirect all missing files to a PHP script called “error.php” in your directory root. You then create this handler:

Reference: http://derickrethans.nl/errorhandling/rasmus-trick.htmlhttp://lerdorf.com/tips.pdf

Page 4: PHP Without PHP—Confoo

aka

ErrorDocument trick

Thursday, March 18, 2010

Often attributed to Rasmus, but actually invented by Stig First you create an ErrorDocument line in your apache.conf. What this does is tell the webserver to redirect all missing files to a PHP script called “error.php” in your directory root. You then create this handler:

Reference: http://derickrethans.nl/errorhandling/rasmus-trick.htmlhttp://lerdorf.com/tips.pdf

Page 5: PHP Without PHP—Confoo

aka

ErrorDocument trick

Smarter Caching

Thursday, March 18, 2010

Often attributed to Rasmus, but actually invented by Stig First you create an ErrorDocument line in your apache.conf. What this does is tell the webserver to redirect all missing files to a PHP script called “error.php” in your directory root. You then create this handler:

Reference: http://derickrethans.nl/errorhandling/rasmus-trick.htmlhttp://lerdorf.com/tips.pdf

Page 6: PHP Without PHP—Confoo

aka

ErrorDocument trick

Smarter Caching

… Rasmus’s Trick (Stig’s trick)

Thursday, March 18, 2010

Often attributed to Rasmus, but actually invented by Stig First you create an ErrorDocument line in your apache.conf. What this does is tell the webserver to redirect all missing files to a PHP script called “error.php” in your directory root. You then create this handler:

Reference: http://derickrethans.nl/errorhandling/rasmus-trick.htmlhttp://lerdorf.com/tips.pdf

Page 7: PHP Without PHP—Confoo

aka

ErrorDocument trick

Smarter Caching

… Rasmus’s Trick (Stig’s trick)

Thursday, March 18, 2010

Often attributed to Rasmus, but actually invented by Stig First you create an ErrorDocument line in your apache.conf. What this does is tell the webserver to redirect all missing files to a PHP script called “error.php” in your directory root. You then create this handler:

Reference: http://derickrethans.nl/errorhandling/rasmus-trick.htmlhttp://lerdorf.com/tips.pdf

Page 8: PHP Without PHP—Confoo

aka

ErrorDocument trick

Smarter Caching

… Rasmus’s Trick (Stig’s trick)

Go into apache.conf (or .htaccess) and

ErrorDocument 404 /error.php

Thursday, March 18, 2010

Often attributed to Rasmus, but actually invented by Stig First you create an ErrorDocument line in your apache.conf. What this does is tell the webserver to redirect all missing files to a PHP script called “error.php” in your directory root. You then create this handler:

Reference: http://derickrethans.nl/errorhandling/rasmus-trick.htmlhttp://lerdorf.com/tips.pdf

Page 9: PHP Without PHP—Confoo

$filepath = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); //or $_SERVER['REDIRECT_URL']$basepath = dirname(__FILE__).DIR_SEP; // Test to see if you can work with itif (false) { //…EDIT…    //output a 404 page    include('404.html'); // see http://www.alistapart.com/articles/perfect404/ for tips    return;} // Generate the file// …EDIT…$data = 'something'; // Don't send 404 back, send 200 OK because this is a pretty smart 404// not a clueless one! http://www.urbandictionary.com/define.php?term=404header(sprintf('%s 200', $_SERVER['SERVER_PROTOCOL']));//Show the fileecho $data; //Store the page to bypass PHP on the next request. Use a temp file with a// link trick in order to avoid race conditions between concurrent PHP// processes.$tmpfile = tempnam($basepath.'tmp','fc');$fp = fopen($tmpfile,'w'); //remove the "_" this is crashing my blog syntax hilighterfputs($fp, $data);fclose($fp);@link($basepath.$filepath, $tmpfile); //suppress errors due to losing raceunlink($tmpfile);

Error.PHP

Thursday, March 18, 2010

What does this trick do? Basically, when a file doesn’t exist, it gives an opportunity for PHP to create the data and return it instead of a 404 error page.

The code above is pretty canonical, the only exceptions are where you branch to show the default error page…

syntax highlighting code:php_value highlight.string '#b02c04' php_value highlight.comment '#8e98a6'php_value highlight.keyword '#96ad53'#php_value highlight.bg '#f1f7d7'php_value highlight.default '#524e37'php_value highlight.html '#95ad53'

Page 10: PHP Without PHP—Confoo

$filepath = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); //or $_SERVER['REDIRECT_URL']$basepath = dirname(__FILE__).DIR_SEP; // Test to see if you can work with itif (false) { //…EDIT…    //output a 404 page    include('404.html'); // see http://www.alistapart.com/articles/perfect404/ for tips    return;} // Generate the file// …EDIT…$data = 'something'; // Don't send 404 back, send 200 OK because this is a pretty smart 404// not a clueless one! http://www.urbandictionary.com/define.php?term=404header(sprintf('%s 200', $_SERVER['SERVER_PROTOCOL']));//Show the fileecho $data; //Store the page to bypass PHP on the next request. Use a temp file with a// link trick in order to avoid race conditions between concurrent PHP// processes.$tmpfile = tempnam($basepath.'tmp','fc');$fp = fopen($tmpfile,'w'); //remove the "_" this is crashing my blog syntax hilighterfputs($fp, $data);fclose($fp);@link($basepath.$filepath, $tmpfile); //suppress errors due to losing raceunlink($tmpfile);

Error.PHP

Thursday, March 18, 2010

What does this trick do? Basically, when a file doesn’t exist, it gives an opportunity for PHP to create the data and return it instead of a 404 error page.

The code above is pretty canonical, the only exceptions are where you branch to show the default error page…

syntax highlighting code:php_value highlight.string '#b02c04' php_value highlight.comment '#8e98a6'php_value highlight.keyword '#96ad53'#php_value highlight.bg '#f1f7d7'php_value highlight.default '#524e37'php_value highlight.html '#95ad53'

Page 11: PHP Without PHP—Confoo

$filepath = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); //or $_SERVER['REDIRECT_URL']$basepath = dirname(__FILE__).DIR_SEP; // Test to see if you can work with itif (false) { //…EDIT…    //output a 404 page    include('404.html'); // see http://www.alistapart.com/articles/perfect404/ for tips    return;} // Generate the file// …EDIT…$data = 'something'; // Don't send 404 back, send 200 OK because this is a pretty smart 404// not a clueless one! http://www.urbandictionary.com/define.php?term=404header(sprintf('%s 200', $_SERVER['SERVER_PROTOCOL']));//Show the fileecho $data; //Store the page to bypass PHP on the next request. Use a temp file with a// link trick in order to avoid race conditions between concurrent PHP// processes.$tmpfile = tempnam($basepath.'tmp','fc');$fp = fopen($tmpfile,'w'); //remove the "_" this is crashing my blog syntax hilighterfputs($fp, $data);fclose($fp);@link($basepath.$filepath, $tmpfile); //suppress errors due to losing raceunlink($tmpfile);

Error.PHP

Ceheck

Thursday, March 18, 2010

…and where you generate the actual data to render to the user.

Page 12: PHP Without PHP—Confoo

$filepath = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); //or $_SERVER['REDIRECT_URL']$basepath = dirname(__FILE__).DIR_SEP; // Test to see if you can work with itif (false) { //…EDIT…    //output a 404 page    include('404.html'); // see http://www.alistapart.com/articles/perfect404/ for tips    return;} // Generate the file// …EDIT…$data = 'something'; // Don't send 404 back, send 200 OK because this is a pretty smart 404// not a clueless one! http://www.urbandictionary.com/define.php?term=404header(sprintf('%s 200', $_SERVER['SERVER_PROTOCOL']));//Show the fileecho $data; //Store the page to bypass PHP on the next request. Use a temp file with a// link trick in order to avoid race conditions between concurrent PHP// processes.$tmpfile = tempnam($basepath.'tmp','fc');$fp = fopen($tmpfile,'w'); //remove the "_" this is crashing my blog syntax hilighterfputs($fp, $data);fclose($fp);@link($basepath.$filepath, $tmpfile); //suppress errors due to losing raceunlink($tmpfile);

Error.PHP

Thursday, March 18, 2010

At the bottom is where the magic happens. It places the generated file directly into the web server path. What this means is that the next request to the same web resource goes directly for that resource without starting up this code and regenerating the data.

Reference:404 defined: http://en.wikipedia.org/wiki/HTTP_404404 discussion: http://www.alistapart.com/articles/perfect404/404 examples: http://www.plinko.net/404/HTTP codes: http://www.urbandictionary.com/define.php?term=404

Page 13: PHP Without PHP—Confoo

PHP without PHP

Thursday, March 18, 2010

PHP never gets instantiated after the first request!

At that point it truly becomes PHP without PHP.

Page 14: PHP Without PHP—Confoo

ParadigmsPrologue #2

Thursday, March 18, 2010

Page 15: PHP Without PHP—Confoo

Code CompleteThe metaphor of Code as

construction comes from this

book…

W e n o w k n o w t h i s i s fundamentally wrong…

Thursday, March 18, 2010

About the book and the metaphor.

The foundation of Steve McConnell’s seminal text, Code Complete, was that software development should be based around the paradigm of construction. But that was fundamentally flawed because of the mythical man-month—the “man-month” term itself originally coming from construction work. We now know McConnell was wrong and software isn’t construction, it is engineering. And we’re called “software engineers,” not “software workers” for this reason: we’re engineers, not construction workers.

Page 16: PHP Without PHP—Confoo

Mythical Man Month“man-month” is a term from

construction work

The premise is that man and

months are interchangeable.

This means that in order to

reach a deadline I simply add

more people to the project.

reorganize notestoo much text

Thursday, March 18, 2010

Rhe foundation of Steve McConnell’s seminal text, Code Complete, was that software development should be based around the paradigm of construction. But that was fundamentally flawed because of the mythical man-month—the “man-month” term itself originally coming from construction work. We now know McConnell was wrong and software isn’t construction, it is engineering. And we’re called “software engineers,” not “software workers” for this reason: we’re engineers, not construction workers.

Page 17: PHP Without PHP—Confoo

too much text

Thursday, March 18, 2010

Page 18: PHP Without PHP—Confoo

5

10

15

20 Tim

e t

o C

Om

pl

et

e T

itl

e

Number of People

paritionablewith trainingtraning + communicationunpartitionable

too much text

Thursday, March 18, 2010

Page 19: PHP Without PHP—Confoo

F i r s t c o n s i d e r s o m e t h i n g l i k e

painting a fence: everything is

partionable (man-month).

5

10

15

20 Tim

e t

o C

Om

pl

et

e T

itl

e

Number of People

paritionablewith trainingtraning + communicationunpartitionable

too much text

Thursday, March 18, 2010

Page 20: PHP Without PHP—Confoo

F i r s t c o n s i d e r s o m e t h i n g l i k e

painting a fence: everything is

partionable (man-month).

…add a constant time for training.

5

10

15

20 Tim

e t

o C

Om

pl

et

e T

itl

e

Number of People

paritionablewith trainingtraning + communicationunpartitionable

too much text

Thursday, March 18, 2010

Page 21: PHP Without PHP—Confoo

F i r s t c o n s i d e r s o m e t h i n g l i k e

painting a fence: everything is

partionable (man-month).

…add a constant time for training.

…add communication cost: n(n-1)/2.5

10

15

20 Tim

e t

o C

Om

pl

et

e T

itl

e

Number of People

paritionablewith trainingtraning + communicationunpartitionable

too much text

Thursday, March 18, 2010

Page 22: PHP Without PHP—Confoo

F i r s t c o n s i d e r s o m e t h i n g l i k e

painting a fence: everything is

partionable (man-month).

…add a constant time for training.

…add communication cost: n(n-1)/2.

Compare to the unpartitionable

(single man)

5

10

15

20 Tim

e t

o C

Om

pl

et

e T

itl

e

Number of People

paritionablewith trainingtraning + communicationunpartitionable

too much text

Thursday, March 18, 2010

Page 23: PHP Without PHP—Confoo

F i r s t c o n s i d e r s o m e t h i n g l i k e

painting a fence: everything is

partionable (man-month).

…add a constant time for training.

…add communication cost: n(n-1)/2.

Compare to the unpartitionable

(single man)

Adding people to a late project

makes it later!

5

10

15

20 Tim

e t

o C

Om

pl

et

e T

itl

e

Number of People

paritionablewith trainingtraning + communicationunpartitionable

too much text

Thursday, March 18, 2010

Page 24: PHP Without PHP—Confoo

Engineer and Architect

graphics

Thursday, March 18, 2010

Software as Engineering vs. other. My title at Tagged is currently “software architect.” And I have a “radical” idea that maybe titles are that way because they mean something. Meaning that if I’m hired as a software architect then I should think like an architect and find my inspiration from architecture.

Page 25: PHP Without PHP—Confoo

1 Fallingwaterorganic, democratic, plasticity, continuity

Thursday, March 18, 2010

So lets find our inspiration from architecture and see how it explains the Funky Caching pattern through three buildings. the first is one known as Fallingwater.

References:Fallingwater logo from: http://www.fallingwater.org/

Page 26: PHP Without PHP—Confoo

Thursday, March 18, 2010

In Eastern mountain range of the United States there is a house that is CANTILEVERed 40 feet above a waterfall. This is one of the most famous buildings by American architect, FRANK LLOYD WRIGHT. In 1991 it was voted as the best all-time work of American architecture by the American Institute of Architects. Even though it is OVER 80KM from the nearest city people over a MILLION PEOPLE have traveled to see it.

Reference:Image from http://commons.wikimedia.org/wiki/File:Falling_Water_01.jpgWikipedia: http://en.wikipedia.org/wiki/FallingwaterFrank Lloyd Wright: http://franklloydwright.org/Home.html

Page 27: PHP Without PHP—Confoo

…including meThursday, March 18, 2010

Yes, including me as a kid. The day it was built, TIME MAGAZINE wrote about it. Because it was a quintessential example of ORGANIC ARCHITECTURE of FLW.

References:Der Spiegel: http://en.wikipedia.org/wiki/Der_Spiegel

Page 28: PHP Without PHP—Confoo

Hatchway Staircase View at the main (living room) level, from the bridge (from east)

Thursday, March 18, 2010

A staircase connects the house directly to the stream below. The stream and waterfall, although not seen, can be heard in all parts of the house. The HATCHWAY that consists of SLIDING GLASS DOORS and the bottom step has no support from below. (FLOAT above like the water floats)

References:http://wright-house.com/frank-lloyd-wright/fallingwater-pictures/06E-hatchway-fallingwater.html

Page 29: PHP Without PHP—Confoo

Beyond the glass Fallingwater: Living room terraces and glass walls (from east).

Thursday, March 18, 2010

WINDOWS WRAP AROUND THE ENTIRE BUILDING so that the building MERGES with the surrounding GREENERY. Similarly the TUNGSTEN LIGHTING and the glasses compliments the FALL FOLIAGE of the region…

Page 30: PHP Without PHP—Confoo

Fall Foliage View from lookout, downstream.

Thursday, March 18, 2010

This is the VIEW that FLW planned for the house.

References:http://wright-house.com/frank-lloyd-wright/fallingwater-pictures/F1SW-fallingwater-in-fall.html

Page 31: PHP Without PHP—Confoo

Fall Foliage View from lookout, downstream.

Thursday, March 18, 2010

Page 32: PHP Without PHP—Confoo

No barriers Detail: corner window at the guest house, from southeast.

Thursday, March 18, 2010

Panes of glass are caulked directly to each other and to the steel frame or stone walls to further symbolize the lack of barriers between the construction and the surrounding nature.

References:http://wright-house.com/frank-lloyd-wright/fallingwater-pictures/34SE-guest-house-window.html

Page 33: PHP Without PHP—Confoo

Existing tree The trellis over the driveway is built to accommodate a tree.

Thursday, March 18, 2010

The driveway trellis has a semi-circular cutaway to accommodate an existing tree.

References:http://wright-house.com/frank-lloyd-wright/fallingwater-pictures/15-tree-in-trellis-fallingwater.html

Page 34: PHP Without PHP—Confoo

Local quarry Living room, west (downstream) side, from southeast

Thursday, March 18, 2010

The stone floor in the living room, quarried from local rocks

http://wright-house.com/frank-lloyd-wright/fallingwater-pictures/livingroom-fallingwater.html

Page 35: PHP Without PHP—Confoo

Existing boulder Living room fireplace and hearth, looking from kitchen door to south windows

Thursday, March 18, 2010

The rock in the foreground is is an original boulder not disturbed from it’s original position.

References:http://wright-house.com/frank-lloyd-wright/fallingwater-pictures/7-living-room-fireplace-hearth.php

Page 36: PHP Without PHP—Confoo

Existing boulder Living room fireplace and hearth, looking from kitchen door to south windows

Thursday, March 18, 2010

The rock in the foreground is is an original boulder not disturbed from it’s original position.

References:http://wright-house.com/frank-lloyd-wright/fallingwater-pictures/7-living-room-fireplace-hearth.php

Page 37: PHP Without PHP—Confoo

Thursday, March 18, 2010

From details like these to the whole view taken in at once, one gets a feeling that, in spite of the SHARP HORIZONTAL AND VERTICAL LINES of the building, the whole lives in harmony with its environment "instead of lording above [it] in an isolated spot as a man-made imposition.” Why is this building as recognizable as any NATURAL WONDER?

Page 38: PHP Without PHP—Confoo

Philosophyorganic,

democratic,

plasticity,

continuity.

Thursday, March 18, 2010

Surveyed the grounds before building. Organic: "form follows function." Wright argued that "form and function are one." Democratic “design should accommodate needs” Plasticity: “physical element should remove barriers.” Continuity “element should be part of nature”

Page 39: PHP Without PHP—Confoo

Why on PHP?

Thursday, March 18, 2010

How prevalent is funky caching? Every time you visit PHP.NET, you use it (need to get the order of needle-haystack by typing http://php.net/strstr). A cynic would say, because PHP is so SLOW TO EXECUTE, it needs solutions like this to perform well. The problem with this argument is that NO WEB LANGUAGE OUTPERFORMS STATIC SERVERS. Becase it trades off speed of execution with SPEED FOR EASE OF DEVELOPMENT. As Andrei mentioned earlier, that is fundamental to its design. In fact, all dynamically-typed scripting languages make this tradeoff.

Page 40: PHP Without PHP—Confoo

Harmony with Environment

Thursday, March 18, 2010

The ubiquity of this trick in the PHP world is because it—like Frank Lloyd Wright's Fallingwater—lives in harmony with its environment. The environment is an APACHE WEB SERVER, persistent data store in the form of a RELATIONAL DATABASE, and the demands of large-scale, CONSUMER-CENTRIC web sites. Would this solution exist without an ErrorDocument handler built into Apache? Would this solution exist if we didn't persist content on a (relatively) slow data store like a database? Would this solution exist if the consumer didn't demand millisecond response time for dynamic content?

Page 41: PHP Without PHP—Confoo

Harmony with Environment

Apache web server: ErrorDocument

Thursday, March 18, 2010

The ubiquity of this trick in the PHP world is because it—like Frank Lloyd Wright's Fallingwater—lives in harmony with its environment. The environment is an APACHE WEB SERVER, persistent data store in the form of a RELATIONAL DATABASE, and the demands of large-scale, CONSUMER-CENTRIC web sites. Would this solution exist without an ErrorDocument handler built into Apache? Would this solution exist if we didn't persist content on a (relatively) slow data store like a database? Would this solution exist if the consumer didn't demand millisecond response time for dynamic content?

Page 42: PHP Without PHP—Confoo

Harmony with Environment

Apache web server: ErrorDocument

Customer-centric: Performance paramount

Thursday, March 18, 2010

The ubiquity of this trick in the PHP world is because it—like Frank Lloyd Wright's Fallingwater—lives in harmony with its environment. The environment is an APACHE WEB SERVER, persistent data store in the form of a RELATIONAL DATABASE, and the demands of large-scale, CONSUMER-CENTRIC web sites. Would this solution exist without an ErrorDocument handler built into Apache? Would this solution exist if we didn't persist content on a (relatively) slow data store like a database? Would this solution exist if the consumer didn't demand millisecond response time for dynamic content?

Page 43: PHP Without PHP—Confoo

Harmony with Environment

Apache web server: ErrorDocument

Customer-centric: Performance paramount

Relational Database: Slow persistence

Thursday, March 18, 2010

The ubiquity of this trick in the PHP world is because it—like Frank Lloyd Wright's Fallingwater—lives in harmony with its environment. The environment is an APACHE WEB SERVER, persistent data store in the form of a RELATIONAL DATABASE, and the demands of large-scale, CONSUMER-CENTRIC web sites. Would this solution exist without an ErrorDocument handler built into Apache? Would this solution exist if we didn't persist content on a (relatively) slow data store like a database? Would this solution exist if the consumer didn't demand millisecond response time for dynamic content?

Page 44: PHP Without PHP—Confoo

Harmony with Environment

Apache web server: ErrorDocument

Customer-centric: Performance paramount

Relational Database: Slow persistence

Harmony with PHP itself…

Thursday, March 18, 2010

The ubiquity of this trick in the PHP world is because it—like Frank Lloyd Wright's Fallingwater—lives in harmony with its environment. The environment is an APACHE WEB SERVER, persistent data store in the form of a RELATIONAL DATABASE, and the demands of large-scale, CONSUMER-CENTRIC web sites. Would this solution exist without an ErrorDocument handler built into Apache? Would this solution exist if we didn't persist content on a (relatively) slow data store like a database? Would this solution exist if the consumer didn't demand millisecond response time for dynamic content?

Page 45: PHP Without PHP—Confoo

Architecture of PHP Modern web architecture

write text to talk about it

Thursday, March 18, 2010

The language itself. PHP is a component of A WHOLE SYSTEM. It’s glue code.

Page 46: PHP Without PHP—Confoo

PHP is “Cheap”

“A project done in Java will cost 5 times as much, take twice as long, and be harder to maintain than a project done in a scripting language such as PHP or Perl.”

—Phillip Greenspun

graphcis moneyshorten quote

Thursday, March 18, 2010

developer time and resources

Page 47: PHP Without PHP—Confoo

PHP is “Scalable”

“That a Java servlet performs better than a PHP script, under optimal conditions [has] nothing to do with scalability. The point is can your application continue to deliver consistent performance as volume increases. PHP delegates all the ‘hard stuff’ to other systems.”

—Harry Fuecks

graphics notes?shortne quote

Thursday, March 18, 2010

shared-nothing architecture

Page 48: PHP Without PHP—Confoo

PHP is “Pragmatic”

“PHP is not about purity in CS principles or architecture; it is about solving the ugly web problem with an admittedly ugly, but extremely functional and convenient solution. If you are looking for purity, you are in the wrong boat. Get out now before you get hit by a wet cat!”

—Rasmus Lerdorf

graphicsshorten quote

Thursday, March 18, 2010

designed to solve the web problem

Could this "ugly, but extremely functional and convenient" web language have been built to solve anything other than the ugly web problem?

Page 49: PHP Without PHP—Confoo

2 Bellefield TowersDesign Hubris

Thursday, March 18, 2010

One block from where my mother used to work, on the corner of Fifth Avenue and Bellefield in Pittsburgh, stands a strange sight…

Page 50: PHP Without PHP—Confoo

make video of wpaking towards?

Thursday, March 18, 2010

If you weren’t in PITTSBURGH IN THE LATE 1980’s you wouldn’t have understood how his could have happened. On this ground once stood the original Bellefield church built in the 1880’s. Since its CONGREGATION HAD BEEN MOVED further down Fifth Avenue, the building was sold a century later to developers trying to exploit the new business attracted by the PITTSBURGH SUPERCOMPUTING CENTER. They wanted to level it and build a new building, but were blocked when people mobilized to SAVE THE OLD TOWER. The developer then proceeded to honor this by DEMOLISH EVERYTHING BUT THE TOWER and building the ironically-named “Bellefield Towers” next to it.

Page 51: PHP Without PHP—Confoo

Gothic Romanesque architecture The current Bellefield Church (two blocks away)

Thursday, March 18, 2010

This is the current Bellefield Church and an example of city architecture of which the tower is one of them…

Page 52: PHP Without PHP—Confoo

Other city towers Allegheny Courthouse Main Tower & Four Tower Types at Jail (and other towers)

Thursday, March 18, 2010

The center is the county courthouse and jail, the top right is the local Korean church, and the bottom right is a private residence in the same neighborhood.

Page 53: PHP Without PHP—Confoo

Tower of Learning

Within spitting distance of Bellefield Towers

Thursday, March 18, 2010

Page 54: PHP Without PHP—Confoo

Carnegie Library Most iconic moment in baseball history

redo buildsbreak out slidesquots

Thursday, March 18, 2010

The photo at the top is was taken from the Cathedral of learning (previous slide).

Page 55: PHP Without PHP—Confoo

Carnegie Library Most iconic moment in baseball history

redo buildsbreak out slidesquots

Thursday, March 18, 2010

The photo at the top is was taken from the Cathedral of learning (previous slide).

Page 56: PHP Without PHP—Confoo

Why is Bellefield Towers so Ugly?

Thursday, March 18, 2010

When faced with a gorgeous 100-year old example of the area’s architecture, INSTEAD OF WORKING WITH THE ENVIRONMENT like Frank Lloyd Wright did with Fallingwater—in the same area of Pennsylvania no less!—the developer simply sawed it off! The CURVED MODERN ARCHITECTURE of the TOWERS of the latter serves only to emphasize how it was built with no consideration of the surrounding environment. I GREW UP WATCHING THIS HAPPEN and it is a LIFE LESSON IN ARCHITECTURAL HUBRIS.

Page 57: PHP Without PHP—Confoo

Design Hubris?

break out slides, graphics

Thursday, March 18, 2010

“I’m a developer, I can make the software conform to my needs.”Oh really? That sounds a lot like trying to “lord over the environment with an isolated man-made imposition.” “But what I mean is it’s all man-made in software, there is no environment.”

Page 58: PHP Without PHP—Confoo

Design Hubris?Frameworks (almost by definition)

break out slides, graphics

Thursday, March 18, 2010

“I’m a developer, I can make the software conform to my needs.”Oh really? That sounds a lot like trying to “lord over the environment with an isolated man-made imposition.” “But what I mean is it’s all man-made in software, there is no environment.”

Page 59: PHP Without PHP—Confoo

Design Hubris?Frameworks (almost by definition)

Develop in the PHP community?break out slides, graphics

Thursday, March 18, 2010

“I’m a developer, I can make the software conform to my needs.”Oh really? That sounds a lot like trying to “lord over the environment with an isolated man-made imposition.” “But what I mean is it’s all man-made in software, there is no environment.”

Page 60: PHP Without PHP—Confoo

Design Hubris?Frameworks (almost by definition)

Develop in the PHP community?

Take over an existing project?

break out slides, graphics

Thursday, March 18, 2010

“I’m a developer, I can make the software conform to my needs.”Oh really? That sounds a lot like trying to “lord over the environment with an isolated man-made imposition.” “But what I mean is it’s all man-made in software, there is no environment.”

Page 61: PHP Without PHP—Confoo

Design Hubris?Frameworks (almost by definition)

Develop in the PHP community?

Take over an existing project?

Limitations of Site Operations? Hosting? or Virtual hosting?

break out slides, graphics

Thursday, March 18, 2010

“I’m a developer, I can make the software conform to my needs.”Oh really? That sounds a lot like trying to “lord over the environment with an isolated man-made imposition.” “But what I mean is it’s all man-made in software, there is no environment.”

Page 62: PHP Without PHP—Confoo

Design Hubris?Frameworks (almost by definition)

Develop in the PHP community?

Take over an existing project?

Limitations of Site Operations? Hosting? or Virtual hosting?

Business needs trump programmer desire?

break out slides, graphics

Thursday, March 18, 2010

“I’m a developer, I can make the software conform to my needs.”Oh really? That sounds a lot like trying to “lord over the environment with an isolated man-made imposition.” “But what I mean is it’s all man-made in software, there is no environment.”

Page 63: PHP Without PHP—Confoo

Design Hubris?Frameworks (almost by definition)

Develop in the PHP community?

Take over an existing project?

Limitations of Site Operations? Hosting? or Virtual hosting?

Business needs trump programmer desire?

Dealt with a user request?

break out slides, graphics

Thursday, March 18, 2010

“I’m a developer, I can make the software conform to my needs.”Oh really? That sounds a lot like trying to “lord over the environment with an isolated man-made imposition.” “But what I mean is it’s all man-made in software, there is no environment.”

Page 64: PHP Without PHP—Confoo

…at Tagged

add slideshow

Thursday, March 18, 2010

cover cube story, (where cubes are good- Yahoo, sales, user QA), cover waterfall process

Page 65: PHP Without PHP—Confoo

…at Taggedbreak out slides

Thursday, March 18, 2010When I joined my current company, they had a couple services written in Java, only Zend Accelerator could code cache their PHP 4 installation, Oracle RAC powered the back-end and development occurred by engineers working in cubes with a relatively heavyweight waterfall development process.Even though I prefer Python to Java for services, we’ve increased our Java development to around 40% of our code base! Even though I prefer MySQL to Oracle, we still use Oracle as our back-end. Even the transition to the open office occurred after it became apparent the company had outgrown the cube-space.

Page 66: PHP Without PHP—Confoo

…at TaggedCubes

break out slides

Thursday, March 18, 2010When I joined my current company, they had a couple services written in Java, only Zend Accelerator could code cache their PHP 4 installation, Oracle RAC powered the back-end and development occurred by engineers working in cubes with a relatively heavyweight waterfall development process.Even though I prefer Python to Java for services, we’ve increased our Java development to around 40% of our code base! Even though I prefer MySQL to Oracle, we still use Oracle as our back-end. Even the transition to the open office occurred after it became apparent the company had outgrown the cube-space.

Page 67: PHP Without PHP—Confoo

…at TaggedCubes

Waterfall process

break out slides

Thursday, March 18, 2010When I joined my current company, they had a couple services written in Java, only Zend Accelerator could code cache their PHP 4 installation, Oracle RAC powered the back-end and development occurred by engineers working in cubes with a relatively heavyweight waterfall development process.Even though I prefer Python to Java for services, we’ve increased our Java development to around 40% of our code base! Even though I prefer MySQL to Oracle, we still use Oracle as our back-end. Even the transition to the open office occurred after it became apparent the company had outgrown the cube-space.

Page 68: PHP Without PHP—Confoo

…at TaggedCubes

Waterfall process Oracle RAC

break out slides

Thursday, March 18, 2010When I joined my current company, they had a couple services written in Java, only Zend Accelerator could code cache their PHP 4 installation, Oracle RAC powered the back-end and development occurred by engineers working in cubes with a relatively heavyweight waterfall development process.Even though I prefer Python to Java for services, we’ve increased our Java development to around 40% of our code base! Even though I prefer MySQL to Oracle, we still use Oracle as our back-end. Even the transition to the open office occurred after it became apparent the company had outgrown the cube-space.

Page 69: PHP Without PHP—Confoo

…at TaggedCubes

Waterfall process Oracle RAC

Java

break out slides

Thursday, March 18, 2010When I joined my current company, they had a couple services written in Java, only Zend Accelerator could code cache their PHP 4 installation, Oracle RAC powered the back-end and development occurred by engineers working in cubes with a relatively heavyweight waterfall development process.Even though I prefer Python to Java for services, we’ve increased our Java development to around 40% of our code base! Even though I prefer MySQL to Oracle, we still use Oracle as our back-end. Even the transition to the open office occurred after it became apparent the company had outgrown the cube-space.

Page 70: PHP Without PHP—Confoo

…at TaggedCubes

Waterfall process Oracle RAC

JavaPHP4

break out slides

Thursday, March 18, 2010When I joined my current company, they had a couple services written in Java, only Zend Accelerator could code cache their PHP 4 installation, Oracle RAC powered the back-end and development occurred by engineers working in cubes with a relatively heavyweight waterfall development process.Even though I prefer Python to Java for services, we’ve increased our Java development to around 40% of our code base! Even though I prefer MySQL to Oracle, we still use Oracle as our back-end. Even the transition to the open office occurred after it became apparent the company had outgrown the cube-space.

Page 71: PHP Without PHP—Confoo

…at TaggedCubes

Waterfall process Oracle RAC

JavaPHP4

Zend Accelerator

break out slides

Thursday, March 18, 2010When I joined my current company, they had a couple services written in Java, only Zend Accelerator could code cache their PHP 4 installation, Oracle RAC powered the back-end and development occurred by engineers working in cubes with a relatively heavyweight waterfall development process.Even though I prefer Python to Java for services, we’ve increased our Java development to around 40% of our code base! Even though I prefer MySQL to Oracle, we still use Oracle as our back-end. Even the transition to the open office occurred after it became apparent the company had outgrown the cube-space.

Page 72: PHP Without PHP—Confoo

Rework

Thursday, March 18, 2010Book on management by the founders of 37 Signals. Their last book was “Getting Real” about web business.

Page 73: PHP Without PHP—Confoo

ReworkFrom the Founders of 37

Signals

Thursday, March 18, 2010Book on management by the founders of 37 Signals. Their last book was “Getting Real” about web business.

Page 74: PHP Without PHP—Confoo

ReworkFrom the Founders of 37

Signals

Thursday, March 18, 2010Book on management by the founders of 37 Signals. Their last book was “Getting Real” about web business.

Page 75: PHP Without PHP—Confoo

ReworkFrom the Founders of 37

Signals

Last Book: “Getting Real”

Thursday, March 18, 2010Book on management by the founders of 37 Signals. Their last book was “Getting Real” about web business.

Page 76: PHP Without PHP—Confoo

Rework

Thursday, March 18, 2010- cliche ridden with few examples “Hannah Montanta” reach for you dreams- “would rather be celebrities than businesspeople.”- 'Meetings are toxic.' In reality, good meetings are good and bad meetings are not good (generalization)- “Planning, they say, is not recommended” - only applies to their business- “They need to stop behaving like children.”- “Outside money is plan”, about why you should never take on third-party investors.37signals reveals that it took money from Bezos Expeditions, the VC company that invests on behalf of the Amazon founder, Jeff Bezos, in 2006.

Page 77: PHP Without PHP—Confoo

Rework“Not Just Bad, but dangerous”

Thursday, March 18, 2010- cliche ridden with few examples “Hannah Montanta” reach for you dreams- “would rather be celebrities than businesspeople.”- 'Meetings are toxic.' In reality, good meetings are good and bad meetings are not good (generalization)- “Planning, they say, is not recommended” - only applies to their business- “They need to stop behaving like children.”- “Outside money is plan”, about why you should never take on third-party investors.37signals reveals that it took money from Bezos Expeditions, the VC company that invests on behalf of the Amazon founder, Jeff Bezos, in 2006.

Page 78: PHP Without PHP—Confoo

Rework“Not Just Bad, but dangerous”

—John Vincent, Leon Restaurants

Thursday, March 18, 2010- cliche ridden with few examples “Hannah Montanta” reach for you dreams- “would rather be celebrities than businesspeople.”- 'Meetings are toxic.' In reality, good meetings are good and bad meetings are not good (generalization)- “Planning, they say, is not recommended” - only applies to their business- “They need to stop behaving like children.”- “Outside money is plan”, about why you should never take on third-party investors.37signals reveals that it took money from Bezos Expeditions, the VC company that invests on behalf of the Amazon founder, Jeff Bezos, in 2006.

Page 79: PHP Without PHP—Confoo

Solutions Consider Environment

Thursday, March 18, 2010Why? Because that is the environment and your solutions have to work within that environment. Anything else is architectural hubris.Let’s say it is the early days of social networking and you join a company that is using Java/J2EE instead of PHP, or Oracle instead of MySQL, or they’re using Perl/Mason instead of your favorite (PHP) framework, as Marco mentioned earlier—there are so many to choose from that the number is second only to Java.Do you go in and say your experience building a CMS or e-store trumps their experience working on a nascent social network? Do you replace all the Java engineers with PHP ones? Do you replace MySQL with Oracle? Do you rewrite the site from scratch using your favorite framework?I’m not saying that in all these instances these architects shouldn’t have made the decisions they did. I am not qualified to answer that since I didn’t work at these places.But what I do know was that in the vast majority of cases, people went in without considering the existing environment. I do know the dynamics of a Facebook.com is different from the dynamics of Gamespot.com or Amazon.com. I do know a social network is different from a CMS or e-store. And all these solutions are very different from ones in enterprise.Like building Fallingwater without getting an adequate survey done, every day people make the mistake of not looking before acting. They try to make PHP look like Java with dollar signs, as Luke mentioned earlier. They expected the environment to conform to their reality so they can lord over it with “some isolated man-made imposition.”

Page 80: PHP Without PHP—Confoo

3 Golden Gate BridgeThe Design Pattern

Thursday, March 18, 2010

I’ve long since moved from the woods of Western Pennsylvania to the San Francisco Peninsula. I am fortunate that my weekly run passes with a near-constant view of the most recognizable architecture in the American West:

References:Image licensed from: http://www.istockphoto.com/file_closeup.php?id=6091847

Page 81: PHP Without PHP—Confoo

design buildquote of goldne gate bridge

Thursday, March 18, 2010

my weekend run

Page 82: PHP Without PHP—Confoo

the other bridge

quote from emperor norton

Thursday, March 18, 2010

What’s interesting is that there are much longer spans in the country and the world. Even in the same city, there exists a beautiful bridge that is both longer and of more utility. And yet this bridge represents the icon of San Francisco and of the state as a whole.

Page 83: PHP Without PHP—Confoo

quotes of sf

Thursday, March 18, 2010

Page 84: PHP Without PHP—Confoo

Thursday, March 18, 2010

Page 85: PHP Without PHP—Confoo

Same problem, different pattern

Original design was hybrid cantilever-suspension.

Replaced by purse suspension

Thursday, March 18, 2010

The original design was for a hybrid cantilever and suspension structure. But it was replaced with a pure suspension design because the former was deemed too ugly. A pure suspension of this length had never been attempted before.

Page 86: PHP Without PHP—Confoo

Art DecoBridge Tower, Lighting,

pedestrial walkway

quote of art deco movemebnt

Thursday, March 18, 2010Irving Morrow designed the bridge tower, lighting, and pedestrian walkways with an entirely Art Deco decorative influence.

Page 87: PHP Without PHP—Confoo

International Orange

Rust colored like the environment it lives in … and

safe.

Thursday, March 18, 2010

The bridge was painted in a specially formulated anti-rust paint in International Orange on demand from locals. The War Department, and others. The Navy alone originally demanded it be painted black with yellow stripes to assure visibility with passing ships. The rust-colored paint evokes the hills of Marin to the north as well as the setting sun. It is natural and visible enough to be safe.

Page 88: PHP Without PHP—Confoo

Part of the whole

Thursday, March 18, 2010

rust-colored suspension-only art deco structure It becomes an icon. Every week I pass by it and am inspired and thankful I can live in so beautiful a city.

Page 89: PHP Without PHP—Confoo

Design Patterns Defined

shorten quote

Thursday, March 18, 2010

This quote is the origin of “design pattern.”

Page 90: PHP Without PHP—Confoo

Design Patterns Defined

“Each pattern describes a

problem which occurs over

a n d o v e r a g a i n i n o u r

e n v i r o n m e n t , a n d t h e n

describes the core of the

solution to that problem, in

such a way that you can use

this solution a million times

over, without ever doing it

the same way twice.”

shorten quote

Thursday, March 18, 2010

This quote is the origin of “design pattern.”

Page 91: PHP Without PHP—Confoo

Certainly iconic Me in front of both icons

Thursday, March 18, 2010

But how are we to know which way to do it? Or even if it is the right pattern to be using in our situation? The answer is found in how both a house in Pennsylvania and a bridge in San Francisco represent ultimate expressions of architecture. They are wholly appropriate for the environment in which they stand.

Page 92: PHP Without PHP—Confoo

Never the same way twice How do you know which one?

How do you know which way?

blend transition in stages

Thursday, March 18, 2010

A cantilever is wholly appropriate to create the floating look of Fallingwater, but that same pattern would disrupted the naturalness of the Golden Gate Bridge. When choosing between a singleton and a global variable, which pattern to use is determined by the environment.

Page 93: PHP Without PHP—Confoo

Funky Caching again

“search for the closest matching valid URL and redirect, and use attempted url text as a DB keyword lookup”

—Rasmus Lerdorf

Thursday, March 18, 2010

the first is in Rasmus’s talk and you can see PHP.NET in others.

Page 94: PHP Without PHP—Confoo

cleanup text

Thursday, March 18, 2010At my previous company, we had the problem where images are stored on the database but need to be generated in multiple sizes and thumbnails and streamed fast to the user. Previews and thumbnails can be dynamically and instantly generated from border parts, primary graphics, colors, and sample font and text and then stored statically on a server using this method. Stuff may be stored in normal form on the database, but representations built dynamically and served statically

Page 95: PHP Without PHP—Confoo

Thursday, March 18, 2010Address complaint about storing in database…Not all images are stored in the database. In fact, at Tagged, not a single image is stored on a database. However, at Plaxo, the admin tool to manage ecard content requires the assets be done by a non-developer but the only way of pushing out filesystem changes is through change control and there is little need of user generated content. In fact, outside e-cards, the entire Plaxo address book database (including the thumbnail photo of yourself) is stored in a database. I’m not the architect of that, nor do I see much a problem with it.What I point out you CAN now get away with putting image content on the database again with this trick. That’s pretty impressive because different assets on a site (statics, javascripts, web pages, user data, application, back-end, corporate site, customer support, etc) are usually managed on an ad hoc basis optimized for the task at hand. Not all of them can resort to using a filesystem push or web tier restart.

Page 96: PHP Without PHP—Confoo

Javascript and CSS compiling & caching

put a graphic or some text

Thursday, March 18, 2010

Recently, Tagged has run across the very same performance (size and number) issues in Javascript. The solution: Funky caching hooked up to a javascript compressor powered by a Java service back-end to dynamically catenate and compress javascripts into a unique URL on demand.

Page 97: PHP Without PHP—Confoo

Thursday, March 18, 2010

We recently imported 1/64th of our production data over to the staging environment for testing, but the user’s images would take too much time and disk space to import. We could just link the images, but then tester’s didn’t know which ones they uploaded and which ones were proxied from the live website. The solution was to spend an hour writing a Funky Caching Proxy. If the image was missing, the ErrorDocument handler would try to grav the image from the production website and add a watermark.

Page 98: PHP Without PHP—Confoo

Thursday, March 18, 2010

Since this is only for testing, there is no need to waste disk space by storing the created file. The performance hit of real-time generation of redundant requests is unnoticeable to Quality Assurance.

Page 99: PHP Without PHP—Confoo

<?php

$watermark = '3129080702_c4e76f71d7_o.png';$dead_url = 'http://example.com/dead_image.png'; // {{{ start_image($filename, &$data)/*** Creates a gd handle for a valid file* @param $filename string the file to get* @param $data array the imagesize* @return resource GD handle*/function start_image($filename, &$data) {    $data = @getimagesize($filename);    if (empty($data)) { return null; }    $data['ratio'] = $data[0]/$data[1];    switch($data[2]) {        case IMG_GIF: return imagecreatefromgif($filename);        case 3: //problem where IMG_PNG is not bound correctly for my install        case IMG_PNG: return imagecreatefrompng($filename);        case IMG_JPG: return imagecreatefromjpeg($filename);        case IMG_WBMP: return imagecreatefromwbmp($filename);        case IMG_XPM: return imagecreatefromxbm($filename);    }    return null;}   // }}}$requestimg = $_SERVER['REDIRECT_URL'];if (!$_SERVER['QUERY_STRING']) {    // redirect user to invalid image    tag_http::redirect($dead_url);    return '';}// grab image to temp {{{$ch = curl_init($_SERVER['QUERY_STRING']);$tempfile = tempnam('/tmp', 'prod_remote_');$fp = f_open($tempfile, 'w'); //again delete the "_"curl_setopt($ch, CURLOPT_FILE, $fp);curl_setopt($ch, CURLOPT_HEADER, 0);curl_exec_($ch); //delete the final "_"curl_close($ch);fclose($fp);// }}}

expand callouts

Thursday, March 18, 2010

Page 100: PHP Without PHP—Confoo

<?php

$watermark = '3129080702_c4e76f71d7_o.png';$dead_url = 'http://example.com/dead_image.png'; // {{{ start_image($filename, &$data)/*** Creates a gd handle for a valid file* @param $filename string the file to get* @param $data array the imagesize* @return resource GD handle*/function start_image($filename, &$data) {    $data = @getimagesize($filename);    if (empty($data)) { return null; }    $data['ratio'] = $data[0]/$data[1];    switch($data[2]) {        case IMG_GIF: return imagecreatefromgif($filename);        case 3: //problem where IMG_PNG is not bound correctly for my install        case IMG_PNG: return imagecreatefrompng($filename);        case IMG_JPG: return imagecreatefromjpeg($filename);        case IMG_WBMP: return imagecreatefromwbmp($filename);        case IMG_XPM: return imagecreatefromxbm($filename);    }    return null;}   // }}}$requestimg = $_SERVER['REDIRECT_URL'];if (!$_SERVER['QUERY_STRING']) {    // redirect user to invalid image    tag_http::redirect($dead_url);    return '';}// grab image to temp {{{$ch = curl_init($_SERVER['QUERY_STRING']);$tempfile = tempnam('/tmp', 'prod_remote_');$fp = f_open($tempfile, 'w'); //again delete the "_"curl_setopt($ch, CURLOPT_FILE, $fp);curl_setopt($ch, CURLOPT_HEADER, 0);curl_exec_($ch); //delete the final "_"curl_close($ch);fclose($fp);// }}}

expand callouts

Thursday, March 18, 2010

Page 101: PHP Without PHP—Confoo

<?php

$watermark = '3129080702_c4e76f71d7_o.png';$dead_url = 'http://example.com/dead_image.png'; // {{{ start_image($filename, &$data)/*** Creates a gd handle for a valid file* @param $filename string the file to get* @param $data array the imagesize* @return resource GD handle*/function start_image($filename, &$data) {    $data = @getimagesize($filename);    if (empty($data)) { return null; }    $data['ratio'] = $data[0]/$data[1];    switch($data[2]) {        case IMG_GIF: return imagecreatefromgif($filename);        case 3: //problem where IMG_PNG is not bound correctly for my install        case IMG_PNG: return imagecreatefrompng($filename);        case IMG_JPG: return imagecreatefromjpeg($filename);        case IMG_WBMP: return imagecreatefromwbmp($filename);        case IMG_XPM: return imagecreatefromxbm($filename);    }    return null;}   // }}}$requestimg = $_SERVER['REDIRECT_URL'];if (!$_SERVER['QUERY_STRING']) {    // redirect user to invalid image    tag_http::redirect($dead_url);    return '';}// grab image to temp {{{$ch = curl_init($_SERVER['QUERY_STRING']);$tempfile = tempnam('/tmp', 'prod_remote_');$fp = f_open($tempfile, 'w'); //again delete the "_"curl_setopt($ch, CURLOPT_FILE, $fp);curl_setopt($ch, CURLOPT_HEADER, 0);curl_exec_($ch); //delete the final "_"curl_close($ch);fclose($fp);// }}}

Thursday, March 18, 2010

Page 102: PHP Without PHP—Confoo

<?php

$watermark = '3129080702_c4e76f71d7_o.png';$dead_url = 'http://example.com/dead_image.png'; // {{{ start_image($filename, &$data)/*** Creates a gd handle for a valid file* @param $filename string the file to get* @param $data array the imagesize* @return resource GD handle*/function start_image($filename, &$data) {    $data = @getimagesize($filename);    if (empty($data)) { return null; }    $data['ratio'] = $data[0]/$data[1];    switch($data[2]) {        case IMG_GIF: return imagecreatefromgif($filename);        case 3: //problem where IMG_PNG is not bound correctly for my install        case IMG_PNG: return imagecreatefrompng($filename);        case IMG_JPG: return imagecreatefromjpeg($filename);        case IMG_WBMP: return imagecreatefromwbmp($filename);        case IMG_XPM: return imagecreatefromxbm($filename);    }    return null;}   // }}}$requestimg = $_SERVER['REDIRECT_URL'];if (!$_SERVER['QUERY_STRING']) {    // redirect user to invalid image    tag_http::redirect($dead_url);    return '';}// grab image to temp {{{$ch = curl_init($_SERVER['QUERY_STRING']);$tempfile = tempnam('/tmp', 'prod_remote_');$fp = f_open($tempfile, 'w'); //again delete the "_"curl_setopt($ch, CURLOPT_FILE, $fp);curl_setopt($ch, CURLOPT_HEADER, 0);curl_exec_($ch); //delete the final "_"curl_close($ch);fclose($fp);// }}}

Thursday, March 18, 2010

Page 103: PHP Without PHP—Confoo

<?php

$watermark = '3129080702_c4e76f71d7_o.png';$dead_url = 'http://example.com/dead_image.png'; // {{{ start_image($filename, &$data)/*** Creates a gd handle for a valid file* @param $filename string the file to get* @param $data array the imagesize* @return resource GD handle*/function start_image($filename, &$data) {    $data = @getimagesize($filename);    if (empty($data)) { return null; }    $data['ratio'] = $data[0]/$data[1];    switch($data[2]) {        case IMG_GIF: return imagecreatefromgif($filename);        case 3: //problem where IMG_PNG is not bound correctly for my install        case IMG_PNG: return imagecreatefrompng($filename);        case IMG_JPG: return imagecreatefromjpeg($filename);        case IMG_WBMP: return imagecreatefromwbmp($filename);        case IMG_XPM: return imagecreatefromxbm($filename);    }    return null;}   // }}}$requestimg = $_SERVER['REDIRECT_URL'];if (!$_SERVER['QUERY_STRING']) {    // redirect user to invalid image    tag_http::redirect($dead_url);    return '';}// grab image to temp {{{$ch = curl_init($_SERVER['QUERY_STRING']);$tempfile = tempnam('/tmp', 'prod_remote_');$fp = f_open($tempfile, 'w'); //again delete the "_"curl_setopt($ch, CURLOPT_FILE, $fp);curl_setopt($ch, CURLOPT_HEADER, 0);curl_exec_($ch); //delete the final "_"curl_close($ch);fclose($fp);// }}}

Thursday, March 18, 2010

Page 104: PHP Without PHP—Confoo

<?php

$watermark = '3129080702_c4e76f71d7_o.png';$dead_url = 'http://example.com/dead_image.png'; // {{{ start_image($filename, &$data)/*** Creates a gd handle for a valid file* @param $filename string the file to get* @param $data array the imagesize* @return resource GD handle*/function start_image($filename, &$data) {    $data = @getimagesize($filename);    if (empty($data)) { return null; }    $data['ratio'] = $data[0]/$data[1];    switch($data[2]) {        case IMG_GIF: return imagecreatefromgif($filename);        case 3: //problem where IMG_PNG is not bound correctly for my install        case IMG_PNG: return imagecreatefrompng($filename);        case IMG_JPG: return imagecreatefromjpeg($filename);        case IMG_WBMP: return imagecreatefromwbmp($filename);        case IMG_XPM: return imagecreatefromxbm($filename);    }    return null;}   // }}}$requestimg = $_SERVER['REDIRECT_URL'];if (!$_SERVER['QUERY_STRING']) {    // redirect user to invalid image    tag_http::redirect($dead_url);    return '';}// grab image to temp {{{$ch = curl_init($_SERVER['QUERY_STRING']);$tempfile = tempnam('/tmp', 'prod_remote_');$fp = f_open($tempfile, 'w'); //again delete the "_"curl_setopt($ch, CURLOPT_FILE, $fp);curl_setopt($ch, CURLOPT_HEADER, 0);curl_exec_($ch); //delete the final "_"curl_close($ch);fclose($fp);// }}}// configure image and dimensions {{{$size_data = array();$im = start_image($tempfile, $size_data);if (!$im) {    unlink($tempfile);    tag_http::redirect($dead_url);    return;}// }}}// get watermark information {{{$wm_data = array();$wm = start_image($watermark, $wm_data);if (!$wm) {    unlink ($tempfile);    tag_http::redirect($dead_url);    return;}// }}}// add watermark {{{if ($size_data['ratio']> $wm_data['ratio']) {    // image is wider format than the watermark    $new_smaller_dim = $wm_data[0] * ($size_data[1]/$wm_data[1]);    $dst_x = ($size_data[0] - $new_smaller_dim)/2;    $dst_y = 0;    $dst_w = $new_smaller_dim;    $dst_h = $size_data[1];} else {    // image is taller format than the watermark    $new_smaller_dim = $wm_data[1] * ($size_data[0]/$wm_data[0]);    $dst_x = 0;    $dst_y = ($size_data[1] - $new_smaller_dim)/2;    $dst_w = $size_data[0];    $dst_h = $new_smaller_dim;;}imagecopyresized($im, $wm, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $wm_data[0], $wm_data[1]);header(sprintf('%s 200', $_SERVER['SERVER_PROTOCOL']));header(sprintf('Content-type: %s',$size_data['mime']));// }}}switch ($size_data[2]) {    case IMG_GIF: imagegif($im); break;    case 3: case IMG_PNG: imagepng($im); break;    case IMG_JPG: imagejpeg($im); break;    case IMG_WBMP: imagewbmp($im); break;    case IMG_XPM: imagexbm($im); break;}imagedestroy($wm);imagedestroy($im);unlink($tempfile);

Thursday, March 18, 2010

Page 105: PHP Without PHP—Confoo

<?php

$watermark = '3129080702_c4e76f71d7_o.png';$dead_url = 'http://example.com/dead_image.png'; // {{{ start_image($filename, &$data)/*** Creates a gd handle for a valid file* @param $filename string the file to get* @param $data array the imagesize* @return resource GD handle*/function start_image($filename, &$data) {    $data = @getimagesize($filename);    if (empty($data)) { return null; }    $data['ratio'] = $data[0]/$data[1];    switch($data[2]) {        case IMG_GIF: return imagecreatefromgif($filename);        case 3: //problem where IMG_PNG is not bound correctly for my install        case IMG_PNG: return imagecreatefrompng($filename);        case IMG_JPG: return imagecreatefromjpeg($filename);        case IMG_WBMP: return imagecreatefromwbmp($filename);        case IMG_XPM: return imagecreatefromxbm($filename);    }    return null;}   // }}}$requestimg = $_SERVER['REDIRECT_URL'];if (!$_SERVER['QUERY_STRING']) {    // redirect user to invalid image    tag_http::redirect($dead_url);    return '';}// grab image to temp {{{$ch = curl_init($_SERVER['QUERY_STRING']);$tempfile = tempnam('/tmp', 'prod_remote_');$fp = f_open($tempfile, 'w'); //again delete the "_"curl_setopt($ch, CURLOPT_FILE, $fp);curl_setopt($ch, CURLOPT_HEADER, 0);curl_exec_($ch); //delete the final "_"curl_close($ch);fclose($fp);// }}}// configure image and dimensions {{{$size_data = array();$im = start_image($tempfile, $size_data);if (!$im) {    unlink($tempfile);    tag_http::redirect($dead_url);    return;}// }}}// get watermark information {{{$wm_data = array();$wm = start_image($watermark, $wm_data);if (!$wm) {    unlink ($tempfile);    tag_http::redirect($dead_url);    return;}// }}}// add watermark {{{if ($size_data['ratio']> $wm_data['ratio']) {    // image is wider format than the watermark    $new_smaller_dim = $wm_data[0] * ($size_data[1]/$wm_data[1]);    $dst_x = ($size_data[0] - $new_smaller_dim)/2;    $dst_y = 0;    $dst_w = $new_smaller_dim;    $dst_h = $size_data[1];} else {    // image is taller format than the watermark    $new_smaller_dim = $wm_data[1] * ($size_data[0]/$wm_data[0]);    $dst_x = 0;    $dst_y = ($size_data[1] - $new_smaller_dim)/2;    $dst_w = $size_data[0];    $dst_h = $new_smaller_dim;;}imagecopyresized($im, $wm, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $wm_data[0], $wm_data[1]);header(sprintf('%s 200', $_SERVER['SERVER_PROTOCOL']));header(sprintf('Content-type: %s',$size_data['mime']));// }}}switch ($size_data[2]) {    case IMG_GIF: imagegif($im); break;    case 3: case IMG_PNG: imagepng($im); break;    case IMG_JPG: imagejpeg($im); break;    case IMG_WBMP: imagewbmp($im); break;    case IMG_XPM: imagexbm($im); break;}imagedestroy($wm);imagedestroy($im);unlink($tempfile);

Thursday, March 18, 2010

Page 106: PHP Without PHP—Confoo

<?php

$watermark = '3129080702_c4e76f71d7_o.png';$dead_url = 'http://example.com/dead_image.png'; // {{{ start_image($filename, &$data)/*** Creates a gd handle for a valid file* @param $filename string the file to get* @param $data array the imagesize* @return resource GD handle*/function start_image($filename, &$data) {    $data = @getimagesize($filename);    if (empty($data)) { return null; }    $data['ratio'] = $data[0]/$data[1];    switch($data[2]) {        case IMG_GIF: return imagecreatefromgif($filename);        case 3: //problem where IMG_PNG is not bound correctly for my install        case IMG_PNG: return imagecreatefrompng($filename);        case IMG_JPG: return imagecreatefromjpeg($filename);        case IMG_WBMP: return imagecreatefromwbmp($filename);        case IMG_XPM: return imagecreatefromxbm($filename);    }    return null;}   // }}}$requestimg = $_SERVER['REDIRECT_URL'];if (!$_SERVER['QUERY_STRING']) {    // redirect user to invalid image    tag_http::redirect($dead_url);    return '';}// grab image to temp {{{$ch = curl_init($_SERVER['QUERY_STRING']);$tempfile = tempnam('/tmp', 'prod_remote_');$fp = f_open($tempfile, 'w'); //again delete the "_"curl_setopt($ch, CURLOPT_FILE, $fp);curl_setopt($ch, CURLOPT_HEADER, 0);curl_exec_($ch); //delete the final "_"curl_close($ch);fclose($fp);// }}}// configure image and dimensions {{{$size_data = array();$im = start_image($tempfile, $size_data);if (!$im) {    unlink($tempfile);    tag_http::redirect($dead_url);    return;}// }}}// get watermark information {{{$wm_data = array();$wm = start_image($watermark, $wm_data);if (!$wm) {    unlink ($tempfile);    tag_http::redirect($dead_url);    return;}// }}}// add watermark {{{if ($size_data['ratio']> $wm_data['ratio']) {    // image is wider format than the watermark    $new_smaller_dim = $wm_data[0] * ($size_data[1]/$wm_data[1]);    $dst_x = ($size_data[0] - $new_smaller_dim)/2;    $dst_y = 0;    $dst_w = $new_smaller_dim;    $dst_h = $size_data[1];} else {    // image is taller format than the watermark    $new_smaller_dim = $wm_data[1] * ($size_data[0]/$wm_data[0]);    $dst_x = 0;    $dst_y = ($size_data[1] - $new_smaller_dim)/2;    $dst_w = $size_data[0];    $dst_h = $new_smaller_dim;;}imagecopyresized($im, $wm, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $wm_data[0], $wm_data[1]);header(sprintf('%s 200', $_SERVER['SERVER_PROTOCOL']));header(sprintf('Content-type: %s',$size_data['mime']));// }}}switch ($size_data[2]) {    case IMG_GIF: imagegif($im); break;    case 3: case IMG_PNG: imagepng($im); break;    case IMG_JPG: imagejpeg($im); break;    case IMG_WBMP: imagewbmp($im); break;    case IMG_XPM: imagexbm($im); break;}imagedestroy($wm);imagedestroy($im);unlink($tempfile);

Thursday, March 18, 2010

Page 107: PHP Without PHP—Confoo

<?php

$watermark = '3129080702_c4e76f71d7_o.png';$dead_url = 'http://example.com/dead_image.png'; // {{{ start_image($filename, &$data)/*** Creates a gd handle for a valid file* @param $filename string the file to get* @param $data array the imagesize* @return resource GD handle*/function start_image($filename, &$data) {    $data = @getimagesize($filename);    if (empty($data)) { return null; }    $data['ratio'] = $data[0]/$data[1];    switch($data[2]) {        case IMG_GIF: return imagecreatefromgif($filename);        case 3: //problem where IMG_PNG is not bound correctly for my install        case IMG_PNG: return imagecreatefrompng($filename);        case IMG_JPG: return imagecreatefromjpeg($filename);        case IMG_WBMP: return imagecreatefromwbmp($filename);        case IMG_XPM: return imagecreatefromxbm($filename);    }    return null;}   // }}}$requestimg = $_SERVER['REDIRECT_URL'];if (!$_SERVER['QUERY_STRING']) {    // redirect user to invalid image    tag_http::redirect($dead_url);    return '';}// grab image to temp {{{$ch = curl_init($_SERVER['QUERY_STRING']);$tempfile = tempnam('/tmp', 'prod_remote_');$fp = f_open($tempfile, 'w'); //again delete the "_"curl_setopt($ch, CURLOPT_FILE, $fp);curl_setopt($ch, CURLOPT_HEADER, 0);curl_exec_($ch); //delete the final "_"curl_close($ch);fclose($fp);// }}}// configure image and dimensions {{{$size_data = array();$im = start_image($tempfile, $size_data);if (!$im) {    unlink($tempfile);    tag_http::redirect($dead_url);    return;}// }}}// get watermark information {{{$wm_data = array();$wm = start_image($watermark, $wm_data);if (!$wm) {    unlink ($tempfile);    tag_http::redirect($dead_url);    return;}// }}}// add watermark {{{if ($size_data['ratio']> $wm_data['ratio']) {    // image is wider format than the watermark    $new_smaller_dim = $wm_data[0] * ($size_data[1]/$wm_data[1]);    $dst_x = ($size_data[0] - $new_smaller_dim)/2;    $dst_y = 0;    $dst_w = $new_smaller_dim;    $dst_h = $size_data[1];} else {    // image is taller format than the watermark    $new_smaller_dim = $wm_data[1] * ($size_data[0]/$wm_data[0]);    $dst_x = 0;    $dst_y = ($size_data[1] - $new_smaller_dim)/2;    $dst_w = $size_data[0];    $dst_h = $new_smaller_dim;;}imagecopyresized($im, $wm, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $wm_data[0], $wm_data[1]);header(sprintf('%s 200', $_SERVER['SERVER_PROTOCOL']));header(sprintf('Content-type: %s',$size_data['mime']));// }}}switch ($size_data[2]) {    case IMG_GIF: imagegif($im); break;    case 3: case IMG_PNG: imagepng($im); break;    case IMG_JPG: imagejpeg($im); break;    case IMG_WBMP: imagewbmp($im); break;    case IMG_XPM: imagexbm($im); break;}imagedestroy($wm);imagedestroy($im);unlink($tempfile);

Thursday, March 18, 2010

Page 108: PHP Without PHP—Confoo

Beyond Funky Caching

Thursday, March 18, 2010

With a bit of creativity this concept can apply to modern applications where instead of caching on the filesystem, you cache in memcache; instead of bypassing the application server, you bypass the web servers themselves with a content distribution network; instead of serving static content from the edge, you serve dynamic pages.Whether to use it and how to use it is always determined by the environment.

Page 109: PHP Without PHP—Confoo

San FranciscoLooking around you for

inspiration

quotes of san francisco?

Thursday, March 18, 2010I hope this tour helps you see software development in a different way—that finding solutions are about using the right solution in a manner that fits with the environment. Even then I realize that we can’t architect structures that work as harmoniously together as a city such as San Francisco. Story of Rounded Rectangles…

Bill Atkinson worked mostly at home, but whenever he made significant progress he rushed in to Apple to show it off to anyone who would appreciate it. This time, he visited the Macintosh offices at Texaco Towers to show off his brand new oval routines, which were implemented using a really clever algorithm. Bill had added new code to QuickDraw (which was still called LisaGraf at this point) to draw circles and ovals very quickly. That was a bit hard to do on the Macintosh, since the math for circles usually involved taking square roots, and the 68000 processor in the Lisa and Macintosh didn't support floating point operations. But Bill had come up with a clever way to do the circle calculation that only used addition and subtraction, not even multiplication or division, which the 68000 could do, but was kind of slow at.

Bill's technique used the fact the sum of a sequence of odd numbers is always the next perfect square (For example, 1 + 3 = 4, 1 + 3 + 5 = 9, 1 + 3 + 5 + 7 = 16, etc). So he could figure out when to bump the dependent coordinate value by iterating in a loop until a threshold was exceeded. This allowed QuickDraw to draw ovals very quickly.

Bill fired up his demo and it quickly filled the Lisa screen with randomly-sized ovals, faster than you thought was possible. But something was bothering Steve Jobs. "Well, circles and ovals are good, but how about drawing rectangles with rounded corners? Can we do that now, too?"

"No, there's no way to do that. In fact it would be really hard to do, and I don't think we really need it". I think Bill was a little miffed that Steve wasn't raving over the fast ovals and still wanted more.

Steve suddenly got more intense. "Rectangles with rounded corners are everywhere! Just look around this room!". And sure enough, there were lots of them, like the whiteboard and some of the desks and tables. Then he pointed out the window. "And look outside, there's even more, practically everywhere you look!". He even persuaded Bill to take a quick walk around the block with him, pointing out every rectangle with rounded corners that he could find.

When Steve and Bill passed a no-parking sign with rounded corners, it did the trick. "OK, I give up", Bill pleaded. "I'll see if it's as hard as I thought." He went back home to work on it.

Bill returned to Texaco Towers the following afternoon, with a big smile on his face. His demo was now drawing rectangles with beautifully rounded corners blisteringly fast, almost at the speed of plain rectangles. When he added the code to LisaGraf, he named the new primitive "RoundRects". Over the next few months, roundrects worked their way into various parts of the user interface, and soon became indispensable.