ID:               37800
 Updated by:       [EMAIL PROTECTED]
 Reported By:      RQuadling at GMail dot com
-Status:           Open
+Status:           Assigned
 Bug Type:         PCRE related
 Operating System: Windows XP SP2
 PHP Version:      5CVS-2006-06-14 (snap)
-Assigned To:      
+Assigned To:      andrei
 New Comment:

While I can agree that your script doesn't output the expected result,
lets Andrei decide what to do here. That parameter exists for a long
time and I don't know if this problem is a regression or if its a
feature :)


Previous Comments:
------------------------------------------------------------------------

[2006-06-15 08:21:37] RQuadling at GMail dot com

Sorry. Shorter script.

<?php
$s_string = '1111111111';
$s_search = '/1/';
$s_replace = 'One ';
$i_limit = 1;
$i_count = 0;


$s_output = preg_replace($s_search, $s_replace, $s_string, $i_limit,
$i_count);
echo "Output = " . var_export($s_output, True) . "\n";
echo "Count  = $i_count\n";

$i_limit = strlen($s_string);
$s_output = preg_replace($s_search, $s_replace, $s_string, $i_limit,
$i_count);
echo "Output = " . var_export($s_output, True) . "\n";
echo "Count  = $i_count\n";
?>

Expected output ...

Output = 'One 111111111'
Count  = 1
Output = 'One One One One One One One One One One '
Count  = 10

Actual output ...

Output = NULL
Count  = 1
Output = 'One One One One One One One One One One '
Count  = 10

2 errors.

1 - preg_replace is mishandling the limit parameter
2 - preg_replace is returning NULL when the limit parameter is NOT the
number of times that the replace can take place.

------------------------------------------------------------------------

[2006-06-14 16:42:49] [EMAIL PROTECTED]

Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc.

If possible, make the script source available online and provide
an URL to it here. Try to avoid embedding huge scripts into the report.



------------------------------------------------------------------------

[2006-06-14 11:03:15] RQuadling at GMail dot com

Description:
------------
The documentation for preg_replace's limit parameter is ...

"The maximum possible replacements for each pattern in each subject
string. Defaults to -1 (no limit)."

So, this suggests that you can set this to limit the number of
replacements when there is the possibility of more than 1 match.

It seems that this is not actually working as such.

The example code is completely contrived.

The code is attempting to insert a single WHERE clause into an existing
SQL statement.

The WHERE clause has to appear before GROUP BY, HAVING, ORDER BY or
OPTION, depending upon which one is present.

The limit parameter is behaving like a "must match x times before
replacement occurs".

The return values for the incorrect behaviour is NULL.

The documentation for preg_replace says 

"If matches are found, the new subject will be returned, otherwise
subject will be returned unchanged."

Which is also incorrect.

Reproduce code:
---------------
<?php
$s_query = 'SELECT Author, COUNT(*) AS Books FROM Authors GROUP BY
Authors HAVING COUNT(*) > 10 ORDER BY Author';
$s_replace = 'WHERE Author LIKE \'A%\' \1';
$s_new_query_all = preg_replace
        (
        "`(GROUP BY|HAVING|ORDER BY|OPTION)`sim", 
        $s_replace,
        $s_query,
        -1,
        $i_count_all
        );

$s_new_query_one = preg_replace
        (
        "`(GROUP BY|HAVING|ORDER BY|OPTION)`sim", 
        $s_replace,
        $s_query,
        1,
        $i_count_one
        );

$s_new_query_two = preg_replace
        (
        "`(GROUP BY|HAVING|ORDER BY|OPTION)`sim", 
        $s_replace,
        $s_query,
        2,
        $i_count_two
        );

$s_new_query_three = preg_replace
        (
        "`(GROUP BY|HAVING|ORDER BY|OPTION)`sim", 
        $s_replace,
        $s_query,
        3,
        $i_count_three
        );

echo <<< END_REPORT
Original Query : $s_query
No limit       : ($i_count_all) $s_new_query_all
Limit to 1     : ($i_count_one) $s_new_query_one
Limit to 2     : ($i_count_two) $s_new_query_two
Limit to 3     : ($i_count_three) $s_new_query_three
END_REPORT;
?>

Expected result:
----------------
Original Query : SELECT Author, COUNT(*) AS Books FROM Authors GROUP BY
Authors HAVING COUNT(*) > 10 ORDER BY Author
No limit       : (3) SELECT Author, COUNT(*) AS Books FROM Authors
WHERE Author LIKE 'A%' GROUP BY Authors WHERE Author LIKE 'A%' HAVING
COUNT(*) > 10 WHERE Author LIKE 'A%' ORDER BY Author
Limit to 1     : (1) SELECT Author, COUNT(*) AS Books FROM Authors
WHERE Author LIKE 'A%' GROUP BY Authors HAVING COUNT(*) > 10 ORDER BY
Author
Limit to 2     : (2) SELECT Author, COUNT(*) AS Books FROM Authors
WHERE Author LIKE 'A%' GROUP BY Authors WHERE Author LIKE 'A%' HAVING
COUNT(*) > 10 ORDER BY Author
Limit to 3     : (3) SELECT Author, COUNT(*) AS Books FROM Authors
WHERE Author LIKE 'A%' GROUP BY Authors WHERE Author LIKE 'A%' HAVING
COUNT(*) > 10 WHERE Author LIKE 'A%' ORDER BY Author

Actual result:
--------------
Original Query : SELECT Author, COUNT(*) AS Books FROM Authors GROUP BY
Authors HAVING COUNT(*) > 10 ORDER BY Author
No limit       : (3) SELECT Author, COUNT(*) AS Books FROM Authors
WHERE Author LIKE 'A%' GROUP BY Authors WHERE Author LIKE 'A%' HAVING
COUNT(*) > 10 WHERE Author LIKE 'A%' ORDER BY Author
Limit to 1     : (1) 
Limit to 2     : (2) 
Limit to 3     : (3) SELECT Author, COUNT(*) AS Books FROM Authors
WHERE Author LIKE 'A%' GROUP BY Authors WHERE Author LIKE 'A%' HAVING
COUNT(*) > 10 WHERE Author LIKE 'A%' ORDER BY Author


------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=37800&edit=1

Reply via email to