Wherein I occasionally rant on various topics including, but not limited to, PHP, Music, and whatever other Topics I find interesting at the moment, including my brain tumor surgery of August 2010.

Thursday, September 13, 2007

Adobe Spams

Today, July 21, 2009, Adobe has once again resurrected the email I gave them in 2007, and has spammed it.

I say again: Adobe spams, boycott Adobe.

For the record:

I loathe Flash.

I mean, even on Windows where it kind of sort of works, it sucks up WAY too much RAM, and WAY too much CPU, and crashes far too often.

Not that anything really works well on Windows (other than their Marketing, Legal, and Bullying Departments) but Flash works particularly badly.

On Linux? Forget it.

I gave up installing the damn thing, even on Windows, about a year ago, and you know what?

I have found that there is not one site with any content worth getting that I am missing out, that I can't find elsewhere.

Maybe your experience is different; Maybe you just can't live without uTube.


But for me, no more Flash, ever again.

Oh yeah, the real reason I hate Adobe is that they are spammers.

They added me to their mailing list, unsolicited, and sent me commercial junk mail.

So unless you want to support spammers, stop using their products.

It's that simple.

Thank you.

Tuesday, July 17, 2007

File Upload Progress Meter

Every week or two, somebody asks how to do a File Upload Progress Meter on the PHP-General mailing list...

Why the BROWSER doesn't provide this feature everybody wants is beyond
my ken.

Surely the browser has some clue how many bytes are uploaded and how
big the file was.

How tricky could it be for Firefox/IE to poke those values into a
couple variables somewhere?

Instead we have a zillion JS hacks by developers generating tons of
traffic back-n-forth to the server to ask it how many bytes it has
received so far...

In fact, why don't the browsers provide a NICE file upload progress meter in the first place, so web designers don't feel the need to re-invent the wheel?

Or even (gasp) some nice hooks involving CSS and Web 2.0 or whatever so web designers can just do this without even needing to know any Javascript?

This certainly would be way more useful than half the crap the browser wars have introduced in the past half decade that we've been needing this feature!

Thursday, July 12, 2007

Too Many "Friends"

Bear with me here, there's a fairly long prologue...

So, here's the thing:

In one of my alter egos, I'm a Talent Buyer at a music venue.

Now, you may not know much about the internal workings of music venues, but, basically, a music venue has about 1000 bands pounding on the doors wanting to play for every available position.

There's nothing we'd love more than for there to be way more fans out there, mind you, so we could actually accommodate about 100 of those artists, instead of just he 1.

Do note that I said 100 of the 1000, not all of them...

90% of everything is still crap.

Anyway, at the email address we've set up specifically for artists to submit a demo, we tend to get a whole lot of friend-link requests to basically all the big social networking sites.

Now, this is going to sound petty, but it's getting pretty dang annoying.

Most of these friend link requests are coming from artists we don't work with.

Many of them are coming from artists we simply can't work with, as they're not the 1 in a thousand.

I daresay a lot of them are coming from the 900 we wouldn't want to work with, even if the the supply/demand went the other way, with way more fans than artists...

Our website pretty clearly asks bands not to add us to their promotional mailing lists. Do we really need to spell it out "and don't send us be-my-friend emails either"?

Anyway, I'm thinking that all these social networking sites should just stop sending out emails on behalf of their users to non-users to invite them to join.

If I want to join your social-networking site, and buy into the whole thing, then fine, I've agreed to get your emails.

But I haven't!

So, really, all these social-networking sites are just thinly-disguised spammers, when you get down to it.

Or maybe there should be some kind of industry-standard minimum proof that the recipient might actually want these dang things, or that the sender actually has an existing relationship.

Knowing an email address is not an existing relationship!

Because it's gotten to the point where a new entrant in the social networking market, to me, just means yet another flurry of invites that I don't really want.

Then I have to spend 20 minutes digging through their site for a place to contact them to say not only to ban that one user from sending me emails, but to ban ALL the users from ever sending me emails.

I don't even want the dang things at my personal address anymore, really, from friends I actually know. It's gotten that bad.

I definitely don't want them from strangers to an email address that was set up for a very specific business purpose.

Am I being too petty?

I don't think so.

We came up with guidelines for the robots, and that seems to have (mostly) worked out.

Can't we come up with guidelines for these social networking / stay in touch sites?

Here are some suggested starting points for guidelines:

If I'm not a member of your site, don't email me more than one invite ever, period.

If I didn't want to join when Lee invited me, I still don't want to join when Fran invites me, okay?

The invite email should provide links including:
    ban this user from ever emailing me again
    ban all users from ever emailing me
    accept invitation
    decline invitation, but join site

Perhaps there should also be a "do not social-network-invite" shared database maintained by the larger existing social networking sites, which other social networking sites could pay a reasonable fee on a per email basis to check against, and a person could register with that one place to not get any invites from any social networking site.

Note that the fee should be large enough to make it prohibitive for spammers to just pay up to garner emails, that it should not actually hand out email addresses but return a YES/NO for a submitted address from the social networking site, but be cheap enough that any serious new social networking site would buy in as a matter of course. Maybe there is no such price-point, but at least give it some thought.

I sure don't want to keep contacting every johnny-come-lately social networking site to ask them to put a ban on their users sending me invites. There are too many of them springing up like weeds.

Wednesday, July 11, 2007


How come this doesn't work:
<button action='<?php mysqli_query($connect,$query)?>'>Click</button>

[sportscaster voice-over]

Joe: Hey Bob, let's look at a slow-motion instant-replay of this common PHP newbie fallacy scenario.
Bob: Sure Joe!
Joe: Okay, so here goes:
  The user requests a HTTP URL document.
  The webserver fires up.
  The webserver finds that it needs PHP to generate the document.
  PHP fires up.
Bob: Wow, look at PHP go! That's fast!
Joe: Yeah, it is fast.
  PHP has generated the document, and spits it out.
Bob: Boy, it's already finished. Hey, it's quit!
Joe: That's right, Bob.
  PHP has FINISHED EXECUTION, and has exited.
  Now watch this!
Bob: Oh boy, I see it coming now...
Joe: Yep, there it is.
  There's some HTML in the browser, trying to execute some PHP code...
Bob: But you can see, PHP has LONG FINISHED and is OUTTA HERE!!!
Joe: That's right, Bob, PHP is simply not around to execute that code.
Bob: So what can you do, Joe?
Joe: Well, if you can live with the browser going back-n-forth to the web-server, with a significant "lag" time...
Bob: Oooh, well, I can see how that might be useful sometimes...
Joe: In those cases, you can use Ajax.
Bob: Anything else?
Joe: Not really. Until you get back to the webserver and PHP, there's just no PHP available. Unless your user is in the extreme minority of uber-PHP-geeks that has installed this EXPERIMENTAL PHP browser plug-in thingie: http://pecl.php.net/package/PHPScript
Bob: Whoa, Joe, I don't think I've ever even heard of anybody who's ever installed that.
Joe: Me neither, though I met Wez Furlong who wrote it, so I have to assume HE has installed it at least once...

[cue to cool Guinness commercial]

Saturday, July 07, 2007

PHP Microsoft Excel Reader and Serial Killer Dates

So, my sister's ex-company of about 6 years that has shut down operations, but still has outstanding loan accounts to collect on...

They have this arcane accounting system and it generates fixed-width field .TXT files, with the wrong dates (with 2-digit year, of course).

The correct dates are in some Excel spreadsheets.

So they wanted a quick hack script to change columns 254 through 259 in some .TXT files based on a simple lookup in some Excel files.

Some developer told them it would take two weeks, and my sister didn't believe that, and they weren't real keen on spending that much $$$.

I told her it was more like a 2 hour job, which might turn into 2 days, when all is said and done.

It actually only took about 8 hours, all told, and most of that was spent in attempting to use various Excel reader PHP scripts that just plain didn't work.

The one up on PHPClasses ends up using parse_url to try to figure out where a local file is, and bombs out. It's a really nifty stream-filter OOP thingie, if it only actually worked...

And what's with all the annoying ads? Maybe less ads would get more traffic would get more revenue... [shrug]

There were several Excel Reader commercial options in the $100 to $200 range, which didn't appeal at all.

There's an Excel Writer in the PEAR Repository, but I couldn't see how to make it read Excel files.

There was some other Excel Reader script, but I forget now why I rejected it. Oh well.

Finally, I found an Excel Reader PEAR package, only it's on Sourceforge instead of in PEAR.

Go figure.

It also had a bug, where it was doing an include of 'OLERead.php' but the file was actually named 'OLERead.inc'

Not quite sure how that passed by a QA process, any QA process but it's trivial to fix.

I did submit a bug report, so hopefully it will get fixed. That is the nice thing about OpenSource.

The example to read a whole sheet in as an array was pretty much all I needed after that quick '.php' -> '.inc' hack.

I didn't even try the reading as a stream thing, since there are only a few thousand accounts.

So I had a nice Excel Reader to do the account number to date lookup.


Then came the joy of Microsoft Excel internal date format...

It's basically a "count" of days from January 1 1900 for the integer part, and a count of seconds for the fractional/decimal part.

Of course, Microsoft aped Lotus 123 and knowingly left in the bug of 1900 being a leap year (it's not)!

So from 0 to 60, the date is "off" by one, and at 60, the bogus date of February 29, 1900 is output. Everything is great from 61 up to a zillion or so where you get to December 31, 9999.

Now, granted, none of these loans date back to the first couple months of 1900, but it's still pretty irksome...

And you'd want a conversion function to be correct and re-usable, rather than something that only works for a limited input set. (Y2K anybody?)

I found a conversion function in C, and ported it to PHP:

I'm not claiming it's the best code ever, and I don't even know what it does, really, as I just changed the variables to have $ in front, and swapped int() function into floor() function.

Slapped in an sprintf instead of returning the individual month/day/year as pass-by-access args, since it seemed easier.

That pretty much sums up the past couple evenings for me.

I occasionally run into a Microsoft devotee who wonders why I hate Microsoft so much.

Really, if this rant doesn't make it clear why I hate Microsoft, I simply cannot hold a rational conversation with you...

It would have been a 2-hour job if MS wasn't so stupid, but it was an 8-hour job because Microsoft is, well, stupid.

Thursday, July 05, 2007

Windows PHP Free Development

Zoe Slattery of IBM has documented exactly how a Windows user would go about hacking PHP source with all free development tools.


I'm not sure if I should leap with joy or cringe in fear, but now any PHP Windows user could manage to write their own custom extension.

I managed to stumble through it once, thanks to Sara Goleman's fantastic articles up on Zend.com:
Extension Writing Part I: Introduction to PHP and Zend

I wonder how long it will be before Microsoft accidentally on purpose breaks things so you can't do this?

Thursday, June 14, 2007

Refund Policy

So I was setting up a new domain today for a website, and for the first time noticed Hostbaby's Refund Policy at the bottom of their contact page:

REFUND POLICY: Anyone who wants a refund can get a refund for any reason.

Made me laugh out loud.

Now, the thing is, I'm sure some readers are saying "Yeah, right" sarcastically.

But I've worked with these guys long enough to know, that if that's what they say their policy is, that's actually their policy.

REFUND POLICY: Anyone who wants a refund can get a refund for any reason.

You can tell them you want to shut down your site and get a refund because your dog ate your homework, and they'll do it.

Plus they don't even charge you until a full month, so you get your site up before the billing starts.

I love this webhost.

PS They also run CDBaby.com where you can buy a zillion Indie CDs, but no major label junk. :-)

Wednesday, June 13, 2007

PHP header location redirect refresh

I haven't posted much, but at php|tek 2007, Chris Shiflett actually said he liked my rant, and that I should post more.

Well, hey, if Chris Shiflett says I oughta do something, I listen.

So, today's rant is about PHP header Location hacks.

First, let's be sure everybody understands what it is:

header("Location: http://example.com");

will re-direct the browser to the URL example.com

Specifically, the PHP tells Apache to issue to the browser a 301 Redirect header to that URL, and then the browser gets that 301 Rediret header and automatically tries to visit that URL.

As pointed out on PHP-General, PHP actually sends a 302 Temporarily Moved rather than a 301 Permanently moved. The rest of the rant still applies, as I simply mis-typed 301 for 302 anyway.

Now this seems really cool at first, perhaps because it is really cool, when used for an appropriate problem.

Unfortunately, many PHP scripters are using this as an Idiom or as a Programming Construct with things like:

if (!logged_in()){
header("Location: login.php");

Now, this does "work" but there are several problems with it.

First and foremost, the HTTP Specs require a complete URI for the location. And while this fragment of a URI might "work" on most browsers, it will, sooner or later, totally mess you up when the browser mis-interprets this.

Specifically, some versions of IE will do the redirect, but won't POST the original data as a redirect should, with this URI fragment. Use the full URL, and IE actually does the right thing, and redirects with all the POST data intact.

You shouldn't use an incomplete URI just because "it works" any more than you should use non-compliant HTML just because it works.

But let's look at this header("Location: ") in a slow-motion instant replay:
User requests page X
Browser uses dog-slow Internet to contact web server.
Web server receives request, hands it off to PHP
PHP responds over dog-slow Internet with 301 Redirect to login.php.
Browser interprets 301 Redirect, hopefully correctly.
Browser uses dog-slow Internet to contact web server.
Web server receives request for login.php, hands it off to PHP
PHP finally spits out the login form.


Maybe you should consider just doing this instead:

if (!logged_in()){
require 'login.php';

And look, ma, no extra round trip through the dog-slow Internet.

Plus, you're not wasting an HTTP connection, which, on a busy server, is a precious resource. Presumably you'd like your website to be popular enough to be busy someday, right?

You're going to end up reading the login.php file in the end anyway. Why would you spend all that time going back and forth to the browser to do it?

And include 'login.php' is no more difficult to read/understand/maintain than the header().

Reserve a header("Location: xxx") for when you really need it: When a document has actually moved and the URL is being retired.

Don't use header("Location: xxx") as a Programming Construct in place of simple if/else and include logic.

PS This same rant applies to the header("Refresh: ") usage as well. Though why you'd want to use that instead of Location: is beyond me, and probably the subject of another rant...