Lazy typing comedy

So, does zero equal 'principal' ?

That's the question that's been driving me nuts today. More accurately, why does PHP think zero and 'principal' are the same thing?

I have this array of people at a school. Some of them are teachers, some of them are principals. In PHP, you're allowed to mix array indices (most other languages would require a Hash), so teachers get inserted with simple numerical indices, the principal gets a text index, "principal".

With me so far?

Now I want to print out a list of all the teachers. Everybody that isn't a principal, in other words. So, everybody that does not have an index of "principal".

<?php foreach ($school['people'] as $i=>$contact) {
if ($i != 'principal') {
?>

Except, when you do this, it strips out the principal and the first person.

The fix I found looks like this:

<?php foreach ($school['people'] as $i=>$contact) {
if ($i !== 'principal') {
?>

In PHP, "!==" means "is the same type and same value as". I think PHP was converting 0 to false, before the comparison as "false is not 'principal'".

I hate this stupid pseudo-language. Grrr!

Permalink • Posted in: php, rant, tech stuffComments (7)

Comments:

Chris Dolan Oct 9, 2006

A problem is that PHP does not distinguish numeric and string equality. Here's a couple of speculative fixes:

1) Put the string first to force string equality:

<?php foreach ($school['people'] as $i=>$contact) {
if ('principal' != $i) {
?>

2) Stringify the number:

<?php foreach ($school['people'] as $i=>$contact) {
if ('principal' != "$i") {
?>

In Perl (a language I'm more proficient in than PHP), this would be:

for (($i=>$contact) = each %{$school->{people}}) {
 if ($i ne 'principal') {

where "ne" is string inequality, as opposed to "!=" which is numeric inequality.

Chris Dolan Oct 9, 2006

More info: look at the second table in the PHP comparison operator docs. It looks like stringifying $i => "$i" is your best bet.

Joshua Oct 9, 2006

Ah, okay. Still, there's some lame conversion going on here.

4 + "10.2 Little Piggies" gives 14.2.

Oy.

I suppose I've grown accustomed to Ruby's "Cannot coerce String errors.

It looks like stringifying $i => "$i" is your best bet.

Hmmm. Maybe; I guess I prefer "!==" in this case. I'm trying to express "if it ain't 'principal'" not "if it isn't the string equivalent of 'principal'".

Chris Dolan Oct 10, 2006

Given PHP's origins in Perl, I consider that numification to be expected and not lame at all. Javascript and other ECMAscript variants work the same way.

Python appears to be more like Ruby:


% python
Python 2.5 (r25:51908, Sep 23 2006, 08:22:23) 
[GCC 4.0.1 (Apple Computer, Inc. build 5247)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 4 + "10.2 little piggies"
Traceback (most recent call last):
  File "", line 1, in 
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Joshua Oct 10, 2006

Actually, JavaScript works rather differently, and more as I would expect:


> 4 + "10.2 little piggies"
"410.2 little piggies"
> 0 != "principal"
true
Joshua Oct 10, 2006

JavaScript also handles string equality better than the others:


> "1" == 1
true
> "1 p" == 1
false
Chris Dolan Oct 10, 2006

Hmm, I was wrong about Javascript I guess.

The Perl and PHP behavior comes from the Unix atof() and atoi() C functions which parse as much numeric content as possible off the front of a string.

Post a comment

  • [required]