Entries Tagged 'PHP' ↓
April 28th, 2008 — Fuzz.com, PHP
The last little while I’ve been writing a new MP3 player for Fuzz using Adobe’s Flex Framework.
OK - first off… before I discuss the problem I gotta say Flex is pretty awesome. I’ve tried Flash before and have always been confused by the whole thing. Timelines, drawing tools & all the other designer-oriented stuff just stumped me. I’m a programmer so getting my head around Flash was just not happening… I don’t think that way. But Flex is fucking cool. The prologue of O’Reilly’s Programming Flex 2 pretty much addressed all my frustration with Flash and explained why I’d like Flex… Well, they’re right. It’s just like writing an app. You get handlers, listeners and all that crap that programmers understand and there’s no timeline or Illustrator-style, insane pen tool. It reminds me a lot of Swing and other shit like that.
Anyways… ya, Flex is cool. But, let’s get to the problem…
Here’s the problem:
The MP3 player streams songs off Fuzz, obviously. Also, downloading a song is quicker than listening to it real time. So a song downloads in 20 seconds, but takes 3 minutes to play… makes sense right. OK but here’s what was going on:
If you hit “play” on the player the song starts downloading and once it has enough it’ll start streaming. But, if you click on a link before the DL finished the request for the new page would not register until then download was complete.
A different manifestation of the same issue comes up when you have 2 browser windows open. Window 1 is playing music while you use window 2 to cruise around the rest of the site. Again, same problem. If you clicked on a link in window two to navigate to a new page nothing would happen until window 1 finished downloading the current song.
Fucked up huh?
I started fucking with every imaginable header in the proxy which serves up the song. Nothing seemed to work. Keep-Alive etc… I tried everything. I started tweaking Apache settings to no avail. Totally had me stumped.
I finally figured it out; The solution was to close the PHP session in the proxy before the code started outputting the MP3’s contents. Why’s this fix things? No idea but it works and I’ll look into “why” tonight at home.
A partial fix was to ignore_user_abort. In the single window case this worked fine but not in the 2 window situation.
Anywho… If anyone’s streaming MP3’s via PHP and wonders why links don’t respond just close your PHP session before spitting out the binary. I’ll check into why this is an issue and update when I understand the technicals.
February 2nd, 2008 — PHP
A couple weeks ago I spent some time setting up a “nice” Eclipse installation at home. My main goal was to get a good PHP development environment working. I’ve been using Eclipse for a while and, for PHP stuff, I’d been using a plugin called PHPEclipse (or something like that). I also had various CSS and JS plugins installed to help out with frontend stuff. It was passable but “eh”. As far as IDE’s go I hold IntelliJ IDEA as the benchmark. Its just good. What I want from an IDE is:
- obviously, syntax hilighting
- a good search mechanism
- a quick way to open files/resources in the project
- code completion
- quick docs
- a decent debugger
Nothing insane really - just standard stuff. My PHP environment covered some of that. Enough where I didn’t bother looking for an alternative for quite some time. The big missing components with my setup were “better” code assist (and docs) and the debugger. Anyways, long story short I wrangled some Eclipse plugins, some Zend extensions and got a pretty damn good environment set up. The core pieces are:
- Eclipse w/ WebTools
- The PDT (PHP Dev Tools) plugin
- Zend’s debugger extensions
The first time through it took me a little while to get everything to play nice but since then I helped everyone at work get things up and running in a matter of minutes (also set up my work box the same way). I’ll go through the setup some other time. Right now I’m redoing the whole thing on my home machine ’cause Eclipse has started to spontaneously crash. Its pretty random and is triggered by creating a new file, navigation code, switching to another editor etc… essentially shit you do all the time. So, while I re-download stuff I figured I’d vent.
Zend just released their IDE built on the PDT too. I’ll check that out some time. I never had a problem paying ~$500 for IntelliJ so if it kicks ass I’ll buy it. The previous Zend IDE just pissed me off 1,000 different ways - but since this one is Eclipse based maybe I’ll dig it and it won’t suck balls. I’d like to see how well it compares to the free route. Maybe I’ll do a write-up to compare em as well as go through how I got the free Eclipse stuff setup.
December 2nd, 2007 — PHP
A buddy of mine read this post about PHP require performance and asked “why would you require a file multiple times?”.
That’s a fair question. There’s a zillion examples why you wouldn’t. Here’s a few obvious reason where you wouldn’t want to:
- using a
require 'header.php' & require 'footer.php' type “chrome” for the site
- using
require_once to ensure a class declaration is available
- load a file with a bunch of common functions
Anyways… there’s a bunch more why reasons to not require the same file more than once but there’s a “oh ya” reasons why you would. I’ll go through one simple case and one more complex case (which ill make even more complex in a following entry).
Zee simple case first:
Let’s say you’re working on a site that has 3 columns. The column’s satisfy the following roles:
- main content
- google ads
- inner site linking (not quite nav)
Topix pretty much has a 3 column layout like this. For the example’s sake let’s assume the middle column has 2 identically styled (colors etc) Google towers stacked one on top of the other. Here’s an awesome mockup of what I’m talking about:
When writing the code for this middle column you have a few choices:
- copy/paste the Google JS twice
- write a PHP function called something like
renderGoogleTower () and call that twice.
- create a file called google.html which would contain the JS and
require that file twice.
The third option above is a pretty legit reason to require the same file twice. Why not right? Copy and pasting the JS sucks (what if you wanted to change a color or 2? You’d have to duplicate code.). With the function call you’d have all this annoying escaping to do… so, the require option sounds like a decent solution.
Alright, let’s check out a more complicate example… a very basic templating system.
This time let’s say you’re working at Digg and you’ve gotta do the UI for this page. Again, you might be tempted to just write a function like renderArticle ($article, $currentUser = null) but when you’re working on a big ass site where the rendered stuff has JS and complex HTML you really don’t wanna do all the HTML in code. Also, its just a good idea to separate your business logic from your ui/display code. If you need more convincing read up on MVC and or Google it.
Now, ignore all the shit on the page like the nav and ads etc and concentrate on the middle of the page. All we’re gonna care about here is this part:
NOTE: i ditched a bunch of the links below each article to keep stuff simple.
The goal here is gonna be to be able to widgetize stuff so that we can render an article with just one function call no matter what page we’re displaying it on. In other words: we want a simple templating system that can give us a super easy way to display a PHP object.
The first thing we’re going to assume is that there’s an Article object that looks like this:
<?
class Article
{
public $title;
public $description;
// simplified
public $url;
public $domain;
// should be a tag object
// but assume a string to keep it easy
public $tag;
public function __construct ($title, $description,
$url, $domain, $tag)
{
$this->title = $title;
$this->description = $description;
$this->url = $url;
$this->domain = $domain;
$this->tag = $tag;
}
}
?>
The next thing we wanna do is sort out the HTML for a single article. That looks something like this lil diddy over here:
article-template.php
<?
// Assumes we have a PHP variable called $article
// $article is a Article object
// we’re ignoring htmlentities () to keep this short
?>
<div class=”article”>
<a class=”title” href=”<?= $article->url ?>“><?= $article->title ?></a>
<div class=”description”>
<span class=”domain”><?= $article->domain ?> —</span>
<?= $article->description ?>
<a class=”more” href=”<?= $article->url ?>“>More…</a>
<span class=”tag”>(<a href=”/<?= $article->tag ?>“ class=”tag”>
<?= $article->tag ?></a>)</span>
</div>
</div>
This gives us a nice and clean template for an Article. At this point we have 2 pieces of the puzzle. We’ve got an object we want to render and a clean PHP file that represents the object in HTML form. Sweet, now we’ve gotta connect the dots and come up with a way to get an Article to article-template.php. Here’s where we finally see another reason for require-ing the same file multiple times.
Since this is just an example we’ll take an easy approach and just write a quick function that can take an object and a template name and make the template render the object. That function could be as simple as:
<?
// $templatePath is a path to the template
// must be in your include_path
// $templateVars is an associative array
// all keys value pairs ($k => $v) in the array will turn into
// new variables in the scope of the template
// the variables’ name will be $k and the value will be $v
function renderTemplate ($templatePath, $templateVars = array ())
{
extract ($templateVars, EXTR_SKIP);
require ($templatePath);
}
?>
You might wanna look up the PHP docs for extract if you’re not familiar with it. Essentially it takes an associative array and creates a bunch of new variables; The names of the variables become the key from the array and the value of the new variable is the value for that key from the array.
So this little renderTemplate ($templatePath, $templateVars = array ()) function takes a path to a template (like article-template.php from above) and an associative array. It first extracts variables from $templateVars to create new variables in the function’s scope, then requires the template. Since a require is pretty much a copy/paste of the code then all the code in the template will have access to all the variables created by extract.
Finally lets make a quick runner script that puts all these pieces together and outputs the HTML generated by our lil tempating system. Everything (except the template) together, in one file, gives us:
<?
// The article class
class Article
{
public $title;
public $description;
// simplified
public $url;
public $domain;
// should be a tag object
// but assume a string to keep it easy
public $tag;
public function __construct ($title, $description,
$url, $domain, $tag)
{
$this->title = $title;
$this->description = $description;
$this->url = $url;
$this->domain = $domain;
$this->tag = $tag;
}
}
// our quick templating function
// $templatePath is a path to the template
// must be in your include_path
// $templateVars is an associative array
// all keys value pairs ($k => $v) in the array will turn into
// new variables in the scope of the template
// the variables? name will be $k and the value will be $v
function renderTemplate ($templatePath, $templateVars = array ())
{
extract ($templateVars, EXTR_SKIP);
require ($templatePath);
}
// Let’s make a couple quick Articles
$articles = array (
new Article (
‘Coolest Squirell EVER’,
‘Bla bla bla bla bla bla bla bla Bla
Bla bla bla bla bla bla bla bla
bla bla bla bla bla bla bla’,
‘http://www.nutsack.com’,
‘nutsack.com’,
‘Design’),
new Article (
‘My iPhone is better than yours’,
‘Some random bathering about an iPhone.
This guy is insane’,
‘http://someIdiotGuy.blogger.com’,
’someIdiotGuy.blogger.com’,
‘Apple’),
new Article (
‘Real Bigfoot caught on tape’,
‘A real video of Bigfoot taken in Washington state.’,
‘http://www.bfro.net’,
‘bfro.net’,
‘Videos’),
);
// quick setup bs
ini_set (‘include_path’, ‘.’);
// Finallly lets make them show up
// article-template.php is in the same folder as this file
foreach ($articles as $a)
{
renderTemplate (‘article-template.php’, array (‘article’ => $a));
}
?>
And there you have it. A overly simple templating “system” in PHP that gives us a valid reason to require the same file more than once. If you want to see it in action:
- click here to download the code
- extract the contents of the zip file to a temporary location in your web root
- finally, navigate to
article.php with your browser
Use the code for fucking around etc. It’s not awesome code so you shouldn’t use in your site… Some day soon I’ll do a writeup which will go through writing a full on templating system in PHP.
November 26th, 2007 — PHP
Dear PHP people… Zend and whoever,
Please allow us (PHP developers) to use arbitrary configuration variables in phg.ini. Also don’t forget to make sure that these arbitrary config. variables can still be set via php_flag and php_value.
Why? Oh, c’mon - for hella reasons; Like when you deploy an app it would be nice to replace stuff like define ('IMAGE_SERVER', 'http://bla_bla_bla.com'); in the ini file instead of including a dumbass constants.php. ‘Cuase correct me if I’m wrong, the web server loads the info from php.ini via the php module when the server/thread starts. Now, using a bunch of define’s in a contants.php file would force all that crap to get loaded for every request and that kinda sucks…
Thanks a million!
Love,
Arin
November 23rd, 2007 — PHP
A quick update on my previous post about the performance of PHP’s require, require_once, include & include_once statements.
Last night I only looked into timing. I ran each statement 1,000 times (on 1,000 different, empty text files) and recorded how long the run through took. Now, I made a quick modification the the “slim” scripts I mentioned in that post to record their memory usage instead of their running time.
I used the same approach for this test:
- run the scripts a bunch of times
- the scripts will log their memory usage to a csv file
- my tally script will run thru the csv file and report average memory consumption
- I’ll look at the results the copy/paste ‘em here
So the results are (reported in bytes):
Ding:test arin$ php tally.php memory_1000.csv
include 371956.000000
include_once 372080.000000
require_once 372080.000000
require 372112.000000
I just checked and my csv file contains 94 entries for each statement (remember, each line in the log is the # bytes of memory used after running a statement 1,000 times).
Again there’s a surprise; require takes more memory than require_once. Also, we see that both include_once and require_once take up the exact same amount of memory. It’s not only the averages for these two that match exactly; every line in the log for include_once and require_once shows the exact same # of bytes of memory is used. Kinda crazy huh? I checked over the scripts a bunch of times to see if something was wrong… but, nope, they look fine to me.
Maybe there’s a fatal flaw in my tests. Hell, if there is I wanna know. I’m not arguing that I’m 100% right - just reporting what my tests show. Maybe this info will help you (or at least spark your interest) or maybe you’ll find something way wrong and help me.
November 22nd, 2007 — PHP
I’ve been working on an MVC framework for PHP for a while now. I started way long ago but never really had enough time to sit down and “really” work on it. Various ideas and chunks of code from this soon-to-exist framework have already been put to use over at Fuzz. Don’t get me wrong - we’re not using some crippled piece of shit at Fuzz, it works & is pretty rad - but I’ve got a bunch to do before I can put this bad boy out as a standalone framework that the public can use.
Anyways… One goal for the framework is to deal with the nuisance of require’s and include’s. Its always easy to fall back on include’ing/require’ing more shit than you actually need. Also, you have all the supposed require_once/include_once performance issues to deal with. With all that in mind I wrote a little, crappy script to do some timing tests on require_once, include_once, require & include. What’s the performance difference between all these?
This script performs a require, require_once, include or include_once on 1,000 DIFFERENT files (0.txt, 1.txt thru 999.txt) and times how long that “batch” takes. Due to the results I saw (which I’ll get to later) I actually didn’t trust it and wrote some other code to verify what I was seeing with this script.
Here’s the code:
the beefy script:
<?
$numFiles = empty ($argv[1]) ? 1000 : $argv[1];
ini_set (‘memory_limit’, -1);
function
doIt ($operation)
{
global $numFiles;
clearstatcache ();
`touch *.txt`;
for ($i = 0; $i < $numFiles; $i++) include “{$i}.txt”;
$startMemoryUse = memory_get_usage ();
$startTime = microtime (true);
for ($i = 0; $i < $numFiles; $i++)
{
eval (“$operation \”{$i}.txt\”;”);
}
$endTime = microtime (true);
$endMemoryUse = memory_get_usage ();
return array (
($endTime - $startTime),
($endMemoryUse - $startMemoryUse));
}
echo “————————————\n”;
if (! file_exists (($numFiles -1) . “.txt”))
{
echo “Prep: touch $numFiles files\n”;
for ($i = 0; $i < $numFiles; $i++) `touch {$i}.txt`;
}
$operations = array (
‘require_once’, ‘require’,
‘include_once’, ‘include’);
shuffle ($operations);
$results = array ();
echo “Running for $numFiles files:\t”,
implode (‘, ’, $operations) , “\n”;
foreach ($operations as $operation)
{
list ($time, $memory) = doIt ($operation);
$results[$operation] = $time;
printf (“%12s: %10d\n”, $operation, $memory);
}
asort ($results);
echo “————————————\n”;
echo “Results:\n”;
$winner = array_slice ($results, 0, 1, true);
$quickest = $winner[key ($winner)];
$fh = fopen (“results_{$numFiles}.csv”, ‘a’);
printf (“\t%12s %10s %10s\n”,
”, ‘faster by’, ‘og. time’);
foreach ($results as $k => $v)
{
fwrite ($fh, “$k\t$v\n”);
if ($v - $quickest)
{
printf (“\t%12s: + %10f %10f\n”,
$k, ($v - $quickest), $v);
}
else
{
printf (“\t%12s: %10s %10f\n”, $k, ‘n/a’, $v);
}
}
?>
So running this on my MacBook I get the following results… oh ya, don’t forget that the timing reflects 1,000 operations.
on MacBook - 1.8Ghz Core Duo
------------------------------------
Running for 1000 files: require, require_once, include_once, include
------------------------------------
Results:
faster by og. time
include_once: n/a 0.088193
require_once: + 0.013137 0.101330
require: + 0.030759 0.118952
include: + 0.045299 0.133492
on Fuzz’s staging server - RHEL on i686
------------------------------------
Running for 1000 files: require_once, include, include_once, require
------------------------------------
Results:
faster by og. time
require_once: n/a 0.026613
include_once: + 0.000050 0.026663
require: + 0.026534 0.053147
include: + 0.026741 0.053354
On both systems x_once turned out the fastest times. I ran the script a bunch of times on both my MacBook and on the Linux box and x_once always registered the fasted times. It looks like my MacBook favors include_once and the Linux box favors require_once… it looks like a 60/40 sort of split.
This didn’t jive with me so I generated 4 new scripts. Each of these scripts ditched all the fluff from the original and just called require_once, require, include_once and include 1,000 times in a row. I ran each of these simplified scripts (honestly, I dunno why I made the first script all beefy anyways…) a bunch of times on both boxes with pretty much the same results as the beefy script.
script generator:
<?
if (empty ($argv[1]))
die (
“usage:\n\tphp {$_SERVER['SCRIPT_NAME']} ” .
“[require|require_once|include|include|once]“
);
$type = $argv[1];
echo “<?\n”;
echo “clearstatcache ();\n”;
echo “ini_set (’memory_limit’, -1);\n”;
echo “`touch *.txt`;\n”;
echo “for (\$i = 0; \$i < 1000; \$i++) include \”{\$i}.txt\”;\n”;
echo “\$start = microtime(true);\n”;
for ($i = 0; $i < 1000; $i++)
{
echo “$type \”{$i}.txt\”;\n”;
}
echo “\$end = microtime(true);\n”;
echo “\$time = (\$end - \$start);\n”;
echo “\$fh = fopen (\”manualResults_1000.csv\”, ’a');\n”;
echo “fwrite (\$fh, \”$type\\t\$time\\n\”);\n”;
echo “echo \”$type: \$time\\n\”;”;
echo “\n?>”;
?>
Something worth noting is the fact that I do a touch and include of each file before I start the timer. The reason for this is cuz I wanted to make sure that each run through had its fair shot of having the txt file available in memory; my cheap attempt at trying to make sure the playing field was fair for each operation. Also, the $operations array is shuffled each time the script is run. I didn’t want to get into a situation where the order the operations ran played a role in their performance.
I added some logging to the end of the scripts so that the timing output was shoved in a cvs. A quick and dirty companion script I wrote would crunch through the csv files to report averages. These resuts were in line with the output of the beefy script.
I’m pretty shocked at the results. I’d always read about the x_once operations being slower. Honestly if it wasn’t for the fact that the simple scripts gave the same results I’d assume I had a bug. This is actually why I wrote the simple scripts… I just didn’t beleive my original numbers.
So, for now, it looks like using include_once or require_once are actually faster than using include or require. Now, the next thing to check out is going to be the difference in memory consumption. I’ll get to that later cuz I’m gonna go drink now
.
Now, don’t get me wrong, I know there’s functional differences between include_once, require_once, include and require. However, for the problem I’m trying to solve any of them will do (it’ll make more sense when I write about my framework).
BTW: Happy Thanksgiving!