Bug #61792 [Com]: preg_replace_callback memory leak
| From: | roman-ak at wmkeeper dot com | Date: | Sun, 06 Jul 2014 16:40:47 +0000 |
| Subject: | Bug #61792 [Com]: preg_replace_callback memory leak | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-186493@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=61792&edit=1
ID: 61792
Comment by: roman-ak at wmkeeper dot com
Reported by: tshaw at oitc dot com
Summary: preg_replace_callback memory leak
Status: Not a bug
Type: Bug
Package: PCRE related
Operating System: OSX 10.7.3
PHP Version: 5.4.0
Block user comment: N
Private report: N
New Comment:
If after problem string add: print 'test';, then been error: "Fatal error: Allowed
memory size". If not add: print 'test';, then been error: "Warning:
preg_replace_callback(): Requires argument 2" But after once error: "Allowed memory
size", no longer appears: "Warning: preg_replace_callback()", allways "Fatal
error: Allowed memory size".
Solution: in config virtual server add:
php_flag eaccelerator.enable 0
php_flag eaccelerator.optimizer 0
Previous Comments:
------------------------------------------------------------------------
[2014-07-06 14:55:20] roman-ak at wmkeeper dot com
It'd a bug, because:
<?
//PHP Version 5.4.4-10, memory=128MB
$source = "123";
//$source = preg_replace_callback('/\d+/', function($m){return $m[0];}, $source); //error
Allowed memory size
//$source = preg_replace_callback('/\d+/', function() use($m){return $m[0];}, $source);
//error Allowed memory size
//$source = preg_replace_callback('/\d+/', create_function('$m', 'return
$m[0];'), $source); //work, but create_function for it's version php is old, about it in
executed not notice, but notice in documentation
//$source = preg_replace_callback('/\d+/', function(){return;}, $source); //error Allowed
memory size
//$source = preg_replace_callback('/\d+/', create_function('',''),
$source); //work, but construction is old
//$f=function(){return;}; $source = preg_replace_callback('/\d+/', $f, $source); //error
Allowed memory size
//function f(){return;}; $source = preg_replace_callback('/\d+/', 'f', $source);
//work, but it's method unacceptable if need do loop and taken out of the loop is also
impossible, because key is change and will protection of engine
if(!function_exists('f')){function f(){return;};} $source =
preg_replace_callback('/\d+/', 'f', $source); //work, not be deprecated and not
suitable for loop
?>
------------------------------------------------------------------------
[2013-04-23 05:27:41] andrew at mcnaughty dot com
Actually I think this bug or something very like it still exists with an anonymous function:
I'm seeing a leak with the following code:
------
$this->contact['email_greeting_display'] = preg_replace_callback(
'@\{(?:contact\.)?([a-z0-9._]*)\}@',
function($matches) use ($prefixes,$contact) {
if ($matches[1] == 'individual_prefix') {
return $prefixes[$contact['prefix_id']];
}
else {
return $contact[$matches[1]];
}
},
$format['greeting']
------
------------------------------------------------------------------------
[2012-04-21 01:46:59] anon at anon dot anon
@tshaw: The problem is that create_function is a nasty old construct that adds a new function every
time you call it, even if the code to compile is the same each time. The created functions are
*permanent* and create_function returns their name only -- so even if the variable containing their
name goes out of scope, the created functions persist. Naturally, 10 million functions take a lot of
memory. It's not technically a bug, just awful language design.
You can create the functions once statically and store their names, or since PHP 5.3.0, you can use
anonymous functions instead. Try this:
function urlDecodeUnreservedChars( $string ) {
$unreserved = array();
$unreserved[] = dechex( ord( '-' ) );
$unreserved[] = dechex( ord( '.' ) );
$unreserved[] = dechex( ord( '_' ) );
$unreserved[] = dechex( ord( '~' ) );
return preg_replace_callback(
array_map(function ($str) { return '/%' . strtoupper($str) . '/x'; },
$unreserved),
function ($matches) { return chr(hexdec($matches[0])); }, $string
);
}
------------------------------------------------------------------------
[2012-04-20 22:45:09] tshaw at oitc dot com
I am totally confused.
You say that its OK for PHP to fail with a memory exhausted error when running a
perfectly valid CLI script that happens to fail on the 180951 iteration? I say
this is absolutely bug!
There may be no memory leak but it surely is a bug as a CLI script that iterates
a long period of time is not out of line.
I respectfully request you reconsider and change this back to a bug.
------------------------------------------------------------------------
[2012-04-20 22:24:28] felipe@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to
report
a bug at http://bugs.php.net/how-to-report.php
There is no memory leak, what happens is that the memory associated to the lambda functions (via
create_function()) is just released in the end of execution.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=61792
--
Edit this bug report at https://bugs.php.net/bug.php?id=61792&edit=1