php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #19926 Can't compare equality on strings using various methods
Submitted: 2002-10-15 23:49 UTC Modified: 2002-10-16 11:56 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: cdfisher at swbell dot net Assigned:
Status: Not a bug Package: Strings related
PHP Version: 4.2.3 OS: Win 2K Server
Private report: No CVE-ID: None
 [2002-10-15 23:49 UTC] cdfisher at swbell dot net
Here is a part of the script that I use to compare the last part number with the next part number.  I have part numbers composed of dashes, numbers and characters (example: 134-4568ATZ).  The purpose of this script is to create an XML file for a parts inventory.  But the same part may fit many different motorcycles and the CSV file has duplicate part numbers on many rows.  They are all sorted by part number so I capture the number I just processed and compare it against the next number.  If they match (which is where my problem lies) then instead of creating another part with the same number, I want to add more child elements to the open parent (I wait to close the parent until I get the next row's data).

The script where I'm trying the comparism looks like this:
if (strcmp($LastPNumber, $data[$i]) != 0){
 echo "New number, New Element<br>";
 $data[$i] = "\t<" . $elements[$i] .">" . $data[$i] ;
}
The $data array elements are trimmed as is the $LastPNumber.  I have tried the == and === and !== and the the preg_match() function and I am stumped.

Here is a readout of the value from comparing, it never changes...
---------------------------------------------------------
Comparing the last Part Number (427-1773) to: next Row Part Number: 427-1812A
Evaluates to 1
New number, New Element
Set the last Part Number to: 427-1812A
Comparing the last Part Number (427-1812A) to: next Row Part Number: 427-1812A
Evaluates to 1
New number, New Element
Set the last Part Number to: 427-1812A
Comparing the last Part Number (427-1812A) to: next Row Part Number: 427-1831A
Evaluates to 1
----------------------------------------------------------
427-1812A above returns the same number (1) as the mis-matches.  According to the documentation, the value should be a 0. This is really screwing up my code.  I just want to compare strings with strings.  I don't care about local or language or having the string be evaluated as an exponent if it has an "e" in it.  Do I have to use Java to get a type cast or what?  I even tried what some other person suggested, concatenate an empty string in an attempt to force a cast.

PHP is such a great tool.  Why should something as simple as this be such a problem?  Thank you for your help with this.

Curtis Fisher


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-10-16 10:59 UTC] cdfisher at swbell dot net
Update to Bug #19926.

I started to suspect that maybe the strings being compared weren't really equal after all.  I used the urlencode function to see if there were hidden characters in either if the strings.  The $LastPNumber variable that I use to assign the $data[0] element contents to showed up as:
---------------------------------------------------------
The urlencode for 427-1831A is %3CItemNumber%3E427-1831A
---------------------------------------------------------
...while the data[0] element always showed up as:
---------------------------------------------------------
The urlencode for 427-1831A is 427-1831A
---------------------------------------------------------
...when run through the same sequence.

So, the mystery solved on one end, but a giant hole opens yet again.  Why is a simple assignment such as:
---------------------------------------------------------
$LastPNumber = trim($data[0]);
---------------------------------------------------------
...resulting in other characters being added (%3CItemNumber%3E)?  Also, the ItemNumber is the column name that is derived at the very begining of this routine by reading the first line of the file into another array named $elements.

Let me start from the beginning.  The routine runs like this:

Read the first line of the CSV file into an array named $elements...
This data will serve as the element Names
Read each subsequent line into an array named $data...
Loop through the $data array for as many count($elements) and create the XML structures like this...
---------------------------------------------------------
$data[$i] = "\t\t<" . $elements[$i] .">" . trim($data[$i]) . "</" . $elements[$i] .">";
---------------------------------------------------------
I use a switch statement to determine the start and end elements and for other special elements in between.

So, what is causing this behavior?  From the trenches I have no idea.  But I found a way around it!

My goal is to keep the part numbers unique in the XML file.  As they exist in the CSV file they are not.  If there are other motorcycles that a part may fit, then they are listed on a separate row with the same part number.  If I had all this data in a database, I could use a DISTINCT on my selection and problem solved!  However, I don't at this point,  I just want to build XML files with PHP.  Is that asking too much?  I don't think so.  Since all the CSV rows are sorted by part number, all I have to do is compare the last part number with the next, if same, don't add the enclosing element and start a new one, just keep looping for this data set adding more child elements.

A simple solution formed by a simple mind.  Mine!  However, the strings refuse to match...
My whole solution was blown away until I figured thus:
All I have to do is check for the existence of the last part number in the next part number!

So that's what I did.  I used the following:
-------------------------------------------------------
if (strpos($ArrayComp[0], $data[$i])) {
	$ev = "They are Equal";
} else {
	$ev = "Equality Failed";
}
echo "Evaluates to: " . $ev . "<br>";
echo "The  position is " . strval(strpos($ArrayComp[0], $data[$i])) . "<br>"
---------------------------------------------------------

And here are the results:

Set the last Part Number to: 427-1831A
Array ( [0] => 427-1831A ) Comparing the last Part Number (427-1831A) to: next Row Part Number: 427-1831A
Evaluates to: They are Equal
The position is 12
New number, New Element
Set the last Part Number to: 427-1831A
Array ( [0] => 427-1831A ) Comparing the last Part Number (427-1831A) to: next Row Part Number: 427-1832A
Evaluates to: Equality Failed
The position is 
New number, New Element
Set the last Part Number to: 427-1832A

Again, the positive number indicates strpos() is working, but not as I would believe it should.  In any case, I found my workaround, but I hope someone much smarter than me can either explain...
A. Why I shouldn't attempt something so simple...
B. That there is a problem when comparing strings with strings
C. Why urlencode() does what it does with this particular assignment and why I shouldn't use it to troubleshoot string problems
D. All of the above

I'm so worn out by all of this, please forgive the verboseness.  I really am trying to use PHP as the platform from which to develop my business with, and since I am a Java and Server Side JavaScript (ECMA262) expert who can't afford all the enterprise stuff from vendors (after being laid off from Sybase) , PHP is a natural choice.  I'm finding a few bumps along the way however.

Sincerely,

Curtis Fisher
President 
Professional Content LLC  
5421 Sterling Ave
Kansas City, MO 64133
Bus:  816.353.4501
Cell: 816.914.8793
http://www.procontent.net
 [2002-10-16 11:32 UTC] cynic@php.net
roman@freepuppy ~ 1036:0 > php -r 'var_dump(urldecode("%3CItemNumber%3E427-1831A"));'
string(21) "<ItemNumber>427-1831A"

fix your code.


 [2002-10-16 11:56 UTC] cdfisher at swbell dot net
I had just realized what I was doing and was in the process of posting a retraction.

Thanks,

Your a busy man of few words...
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sun Oct 20 03:01:26 2019 UTC