Bug #61792 [Com]: preg_replace_callback memory leak

From: 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

« previous php.bugs (#186493) next »