From:             RQuadling at GMail dot com
Operating system: Windows XP SP2
PHP version:      5CVS-2006-06-14 (snap)
PHP Bug Type:     PCRE related
Bug description:  preg_replace limit parameter introduces odd behaviour

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 bug report at http://bugs.php.net/?id=37800&edit=1
-- 
Try a CVS snapshot (PHP 4.4): 
http://bugs.php.net/fix.php?id=37800&r=trysnapshot44
Try a CVS snapshot (PHP 5.2): 
http://bugs.php.net/fix.php?id=37800&r=trysnapshot52
Try a CVS snapshot (PHP 6.0): 
http://bugs.php.net/fix.php?id=37800&r=trysnapshot60
Fixed in CVS:                 http://bugs.php.net/fix.php?id=37800&r=fixedcvs
Fixed in release:             
http://bugs.php.net/fix.php?id=37800&r=alreadyfixed
Need backtrace:               http://bugs.php.net/fix.php?id=37800&r=needtrace
Need Reproduce Script:        http://bugs.php.net/fix.php?id=37800&r=needscript
Try newer version:            http://bugs.php.net/fix.php?id=37800&r=oldversion
Not developer issue:          http://bugs.php.net/fix.php?id=37800&r=support
Expected behavior:            http://bugs.php.net/fix.php?id=37800&r=notwrong
Not enough info:              
http://bugs.php.net/fix.php?id=37800&r=notenoughinfo
Submitted twice:              
http://bugs.php.net/fix.php?id=37800&r=submittedtwice
register_globals:             http://bugs.php.net/fix.php?id=37800&r=globals
PHP 3 support discontinued:   http://bugs.php.net/fix.php?id=37800&r=php3
Daylight Savings:             http://bugs.php.net/fix.php?id=37800&r=dst
IIS Stability:                http://bugs.php.net/fix.php?id=37800&r=isapi
Install GNU Sed:              http://bugs.php.net/fix.php?id=37800&r=gnused
Floating point limitations:   http://bugs.php.net/fix.php?id=37800&r=float
No Zend Extensions:           http://bugs.php.net/fix.php?id=37800&r=nozend
MySQL Configuration Error:    http://bugs.php.net/fix.php?id=37800&r=mysqlcfg

Reply via email to