php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #48015 implode giving wrong results
Submitted: 2009-04-19 11:20 UTC Modified: 2009-12-13 17:02 UTC
From: blackmagic at computer dot org Assigned:
Status: Not a bug Package: PostgreSQL related
PHP Version: 5.2.9 OS: Centos 5.3
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: blackmagic at computer dot org
New email:
PHP Version: OS:

 

 [2009-04-19 11:20 UTC] blackmagic at computer dot org
Description:
------------
A Postgresql query returns an array. If the array is imploded each 
value in the original array appears twice in the implosion.

Assume a Postgresql result array contains $array[0], $array[1], 
$array[2]; 
$x=implode ('|', $array) puts
$array[0]|$array[0]|$array[1]|$array[1]|$array[2]|$array[2] into $x.
$x=$array[0]. '|' . $array[1]. '|' . $array[2]; works fine.
Why is there a difference?

Reproduce code:
---------------
<?php
$company;                                                                                          $details;                                                                                           $index;                                                                                  
require_once('../functions/sql_functions.inc');                                                    database_connect();                                                                                $db_query = "SELECT * FROM company ORDER BY id ";
database_query(__FILE__, __LINE__);                                                            if ($db_rows == 0) echo $DB_EMPTY_FILE;                                                                                                                      
else {
for ($index=0; $index<$db_rows; $index++) {                                                                         $details = pg_fetch_array($db_result, $index);                                                      $company[$index] = implode('|', $details); }   //THE BUG IS HERE//                                                     $details = implode('^', $company);                                                                   echo "$details"; }                                                                                                                                                     


Expected result:
----------------
I expected to see:
$company[$index] = $details[0]|$details[1]|$details[2].




Actual result:
--------------
Actual result:
$company[$index] = 
$details[0]|$details[0]|$details[1]|$details[1]|$details[2]|$details[
2].

This program was working fine until I changed 
$company[$index] = $details[0]. '|' . $details[1]. '|' . $details[2];
to
$company[$index] = implode('|', $details);




Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-04-19 14:18 UTC] jani@php.net
Try 'var_dump($company);' and it should be clear..
 [2009-04-19 23:13 UTC] blackmagic at computer dot org
The scripts in which this implode problem is occurring are remote scripts which are called from a browser by AJAX. AJAX sends the result of 'echo $details' back to the browser. If an error occurs during the running of a script 'echo $details' will return an appropriate error message. Debugging these scripts is more difficult than debugging PHP code that's embedded in HTML code. 

Since var_dump doesn't return any value I can't see how var_dump($company) is going to help me with scripts of this type.

I tried 'echo "var_dump($company)"' and the answer was 'var_dump Array'.

This script snippet works:
for ($index=0; $index<$db_rows; $index++) { 
   $details = pg_fetch_array($db_result, $index);
   $company[$index] = $details[0] . '|' . $details[1] . '|' . $details[2];
} 
$details = implode('^', $company);
echo "$details"; 
'echo "$details"' returns "1|2|3".

This script snippet doesn't work:
for ($index=0; $index<$db_rows; $index++) { 
   $details = pg_fetch_array($db_result, $index);
   $company[$index] = implode('|', $details);
}
$details = implode('^', $company);
echo "$details"; 
'echo "$details"' returns "1|1|2|2|3|3".

The only difference between the two scripts is the third line, where the array returned by pg_fetch_array() is imploded in the script that doesn't work. This suggests to me that there's something unusual about arrays returned by pg_fetch_array(), ie, they are treated differently by implode().
 [2009-04-20 01:39 UTC] scottmac@php.net
Jani was trying to get you see to that pg_fetch_array has two entries because it has both the numeric keys AND the column name.

It's quite clearly in the manual that this is the default behavior of pg_fetch_array. There is a third parameter you can add to only return numeric keys and therefore resulting in one set when you implode.
 [2009-04-20 04:22 UTC] blackmagic at computer dot org
I understand that the array contains the column names and the corresponding key values.

The problem is I'm not getting back the column names and the key values, I'm getting the key values twice.

I thought I would try something else:
foreach($details as $value) $result .= ($value . '|'); 
instead of $company[$index] = implode('|', $details);

The results are the same for the implode() method and the foreach() method: The key values are doubled up in the result the script sends back to the browser.

I've captured the result with a window.alert, but can't paste it into this reply. I'm sending it to you as a separate e-mail with an Word attachment.

Thanks for your assistance.

MJR
 [2009-04-20 04:53 UTC] blackmagic at computer dot org
Changing pg_fetch_array() to:
$details = pg_fetch_array($db_result, $index, PGSQL_NUM);   
produces correct results with the implode() and foreach() methods. But it doesn't explain the behaviour I've been experiencing before including the PGSQL_NUM parameter in the parameter list.

Clearly I was getting a result that wasn't the intended result, ie, instead of getting values and column names I was getting repeated values.
 [2009-04-20 08:18 UTC] jani@php.net
Like already said above: By default the function returns all fields twice. Once with numeric index and once with the field name as the index.
 [2009-04-20 09:07 UTC] blackmagic at computer dot org
Why would the function return the data twice? What good is that to anyone?

If you were to say 'it returns the data and the column headings in default mode' I would say 'that's useful'. However that's not what the function is doing in default mode. It is returning the data twice, which is of no use to anyone.
 [2009-04-20 10:46 UTC] scottmac@php.net
The default value is PGSQL_BOTH so I can use

$result[0] OR $result['columnName']

That is the reason for this, if you don't want to then change the parameter like you've done. The end.

It's been this way for several years and changing it would break backwards compatibility.
 [2009-04-20 12:32 UTC] blackmagic at computer dot org
Scott,

OK. I know how to fix the problem now.

Thanks for getting back to me. 

MJR
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun May 19 15:01:31 2024 UTC