If you’re a PHP programmer, chances are you’ve either run across PEAR or could get some excellent use out of it. PEAR is an acronym for PHP Extension and Application Repository. The creators and maintainers of PEAR encourage you to pronounce it just like the fruit with the same spelling. But you’ll get more than fiber from PEAR, as you’ll learn when you read the rest of this article…
A snippet from my article at codewalkers: The PEAR Package Tour: PEAR Basics.

OSWD: Two Designs
Open Source Web Design
If you’re mainly a programmer, but would love to turn out sites with a bit more fit and finish, this site is for you. They provide packaged “site designs” which include sample HTML, css and images in a ready-to-download zip file. Lots of styles to choose from, and frequent new additions make it very helpful. [via lifehacker]
MySQL Performance Blog
This is one of those sites/blogs that you find while researching one topic, and then just keep reading and reading. Tons of well written, informative and helpful entries. Great discussion in the comments and on the attached forums.
The post that first sucked me in was Why MySQL could be slow with large tables ?
Benchmarking [php] magic
A great entry that considers the cost of many of the new features in the PHP5 object model. Also situated on another great blog that’s worth adding to your feed collection.
Amazon SimpleDB
A very interesting addition to their much talked about Web Service suite, SimpleDB provides a database (or directory service) in their computing cloud, along side S3, EC2 and others. With a pay-as-you-go model and some interesting features, this is the kind of environment that is sure to foster some awesome new projects.
Brady Forrest provides a great overview of the product and pricing on O’Reilly Radar.

Don’t let the lights go out on your site.
At some point, most successful LAMP applications will reach a critical mass of users, usage, data or other milestone, and a previously smooth running application will grind to a halt. Sometimes the degradation comes in waves, a blessing and a curse — it’s harder to troubleshoot periodic slow-downs, but it will affect fewer of your users. In either case, the first step to solving your problem is generally the same… Better logging. While analysis of the code and system may be helpful, the real bottlenecks are rarely obvious. (Or you wouldn’t have written the code that way, to begin with.)
So, to the point: you’re in this situation, the app is in production, what steps can you take to find the bottlenecks?
my.cnf (often /etc/mysql/my.cnf), and ensure that you have settings like this:set-variable=long_query_time=1
log-slow-queries=/var/log/mysql/slow_query.log
/var/log/mysql/mysql.err) for any errors along the lines of “Could not use /var/log/slow_query.log for logging (error 13)”_. If you see these, create the @slowquery.log@ and set it’s ownership to that of your mysql user.slow_query.log will begin to accumulate queries. The actual format of the slow log is bit verbose, but mysqldumpslow, a perl script included with most mysql installations can parse it and produce some more meaningful output. It will take various integers in your queries (a user_id, thread_id, etc) and generalize them, so you can locate types, instead of specific queries.> mysqldumpslow -t=10 -s=t /var/log/slow_query.log
Reading mysql slow query log from /var/log/slow_query.log
Count: 46 Time=80.46s (3701s) Lock=0.00s (0s) Rows=512311 (117447821), bob[bob]@[10.0.0.32]
SELECT * FROM forum_posts
Count: 26 Time=68.26s (1775s) Lock=0.00s (0s) Rows=426 (117447821), bob[bob]@[10.0.0.32]
SELECT * FROM forum_posts WHERE thread=N
Count: 120 Time=3.52s (422s) Lock=0.63s (76s) Rows=58.0 (6960), bob[bob]@[10.0.0.32]
SELECT authors FROM forum_posts WHERE lastpost > N
...
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common CustomLog /usr/local/apache/logs/access_log common </pre>
Whichever log format is being used, this is the name at the end of theCustomLogdirective, you’re going to make a copy of thatLogFormat, give it a name like “commondebug”, and switch the CustomLog directive to use this format.
The fields you will be adding are:
*%T– The time taken to server the request in seconds
*%{mod_php_memory_usage}n– Memory used by PHP in bytesLogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %T %{mod_php_memory_usage}n" combineddebug LogFormat "%h %l %u %t \"%r\" %>s %b %T %{mod_php_memory_usage}n" commondebug CustomLog /usr/local/apache/logs/access_log commondebug </pre>
At this point, you’ll be collecting some great data in you apache logs. You can get some good information with some quick shell magic, like so:> awk '{printf("%07d\t%d\t%s\n", $(NF), $(NF-1), $7)}' access_log | sed 's/\?.*//' | sort -g -k1 0001232 0 /baz.php 0001232 0 /bar.php ... 1712160 0 /foo.php 1717640 0 /foo.php 1907800 0 /foo.php 2010840 0 /foo.php </pre>
Replace,-k1with-k2to sort by the delivery times. Keep in mind, delivery times will include the time to send the bytes over the network — http clients can do screwy things, and you’ll occasionally see anomalous data including 120+ second connects where the client just stopped accepting packets, but didn’t close the socket.
From here, you’ll want to examine each of the memory-hogging scripts, and anything which is consitently long-running.
php.ini on their production servers. (This is a good idea, preventing the revelation of any inappopriate information to end users.)php.ini to include lines such as these:error_reporting = E_ALL & ~E_NOTICE ; Show all errors except for notices
display_errors = Off ; Do not print out errors (as a part of the HTML script)
log_errors = On ; Log errors into a log file
error_log = "/var/log/php_error.log" ; log errors to specified file
#!/usr/bin/perl
my $URL_TO_TEST = 'http://test.test/test.test';
my $THRESHOLD = 2;
open(my $log, '>>status_log.txt');
while (1) {
my $start = time();
`curl "$URL_TO_TEST" > /dev/null`;
my $took = time() - $start;
if ($took > $THRESHOLD) {
print $log "$took seconds load ::";
print $log `date`;
print $log "\n\n";
print $log `vmstat -a`;
print $log "\n\n";
print $log `uptime`;
print $log "\n\n";
print $log `ps awux`;
print $log "\n\n";
print $log `mysqladmin -hHOST -uUSER -pPASSWORD processlist`;
print $log "----------------------------------------------\n\n";
}
sleep(30);
}
There is certainly more data you can collect, but the steps above should be enough to start troubleshooting your performance woes. At some point, I should really write about what to do once you’ve found the trouble.