Navigate
Home
ArticleWiki
Forum
Journal
Search
Newsletter
Links
Tech News
expertsrt.com
Welcome Guest.
Username:

Password:

Remember me

Recurse Function Causing Apache Child Process To Restart
Welcome, Guest. Please login or register.
November 23, 2008, 06:28:47 AM
11307 Posts in 1250 Topics by 501 Members
Latest Member: rosaline
Experts Round Table Network  |  Serverside Technology  |  PHP  |  Recurse Function Causing Apache Child Process To Restart « previous next »
Pages: [1]
Author Topic: Recurse Function Causing Apache Child Process To Restart  (Read 405 times)
CrYpTiC_MauleR
Site Builder

Offline Offline

Posts: 489



WWW
« on: January 28, 2008, 08:44:56 PM »

Code
Language: php (GeSHi-highlighted)
<?php
 
   function recurse($func, $args, $keys = true)
   {
       if (is_string($args[0]))
       {
           return call_user_func_array($func, $args);
       }
       else if (is_array($args[0]))
       {
           $data = $args[0];
           unset($args[0]);
           $new_data = array();
           foreach ($data as $key => $value)
           {
               if ($keys)
               {
                   $key = call_user_func_array($func, array($key, $args));
               }
           $new_data[$key] = (is_string($value))
               ? call_user_func_array($func, array($value, $args))
               : recurse($func, array(array($key => $value), $args));
           }
           return $new_data;
       }
   }
 
   function test($data, $pad = false)
   {
       $data = strtoupper($data);
       if ($pad)
       {
           $data = '___' . $data . '___';
       }
       return $data;
   }
 
$array = 'mmm';
//$array = array('bbb', 'ccc', array('ddd', 'eee' => 'ddd', array('fff')));
echo test('aaa', true);
$array = recurse('test', array($array, true));
print_r($array);
 
?>

I made this recurse function to apply any function to both the key and value of an array or just a string recursively. But for some reason when I use a multidimensional array it causes Firefox to say the following:

"The connection to the server was reset while the page was loading."

Checking the Apache error logs says this:

[notice] Parent: child process exited with status 128 -- Restarting.

I can't spot the logic problem with the function, is there an endless loop I don't see? If that is the case would Apache just not exhaust its resources opposed to having the child process terminate? Any insight on what could be causing this?
Logged

[x] Fight | www.crypticmauler.com
"You must be
VGR
Mentor

Offline Offline

Posts: 682



WWW
« Reply #1 on: February 02, 2008, 02:13:58 PM »

well, I tried it on my own server and I received quasi instanatly this answer :
___AAA______MMM___

I don't know if it's correct of not, but I didn't get any error nor infinite loop

perhaps you could check out your server signature and compre it to mine : Apache/2.2.6 (Win32) PHP/5.2.5
Logged

techie overlord, answers all kind of questions on http://www.europeanexperts.org
CrYpTiC_MauleR
Site Builder

Offline Offline

Posts: 489



WWW
« Reply #2 on: February 03, 2008, 08:59:10 AM »

You need to uncomment:

//$array = array('bbb'.....

I put a test $array before to show that functions work without an array, the commented line is the one that when ran will cause the issue.
Logged

[x] Fight | www.crypticmauler.com
"You must be
VGR
Mentor

Offline Offline

Posts: 682



WWW
« Reply #3 on: February 04, 2008, 12:23:18 PM »

you sure have a problem. I got no dramatic error nor loop, but saw this :
PHP Fatal error:  Allowed memory size of 16777216 bytes exhausted (tried to al
locate 6944 bytes) in *.php on line 13


line 13 is your recurse() line :
            foreach ($data as $key => $value)


add some tracing...
Logged

techie overlord, answers all kind of questions on http://www.europeanexperts.org
GrandSchtroumpf
Mentor

Offline Offline

Posts: 409



« Reply #4 on: February 09, 2008, 07:09:38 PM »

This works...
I added a separate $data argument to the transform function.  It simplifies the code.
Code
Language: php (GeSHi-highlighted)
<?php

function transform($data, $func, $args, $process_keys_flag = true) {
 
if (is_string($data)) {
// String => apply function on string
return call_user_func_array($func, array_merge(array($data), $args));
}
 
else if (is_array($data)) {
// Array => apply transform on keys and values
$new_data = array();
foreach ($data as $key => $value) {
$new_value = transform($value, $func, $args, $process_keys_flag);
if (is_string($key) && $process_keys_flag) {
$new_key = transform($key, $func, $args);
$new_data[$new_key] = $new_value;
}
else {
$new_data[] = $new_value;
}
}
return $new_data;
}
 
}
 
function test($data, $pad = false, $pad2 = false) {
 
$data = strtoupper($data);
if ($pad) {
$data = '___' . $data . '___';
}
if ($pad2) {
$data = 'xxx' . $data . 'xxx';
}
return $data;
 
}
 

$array = array('bbb', 'ccc', array('ddd', 'eee' => 'ddd', array('fff')));
 
echo "<pre>before transform: ";
print_r($array);
echo "</pre>";
 
$array2 = transform($array, 'test', array(true, true));
echo "<pre>after transform (true, true): ";
print_r($array2);
echo "</pre>";

$array3 = transform($array, 'test', array(true, false));
echo "<pre>after transform (true, false): ";
print_r($array3);
echo "</pre>";

$array4 = transform($array, 'test', array(false, true));
echo "<pre>after transform (false, true): ";
print_r($array4);
echo "</pre>";

?>
Logged
CrYpTiC_MauleR
Site Builder

Offline Offline

Posts: 489



WWW
« Reply #5 on: February 10, 2008, 07:55:54 PM »

I'll test the code when I get on my server, thanks.

Do you happen to know what the problem was? I still don't see what went wrong.
Logged

[x] Fight | www.crypticmauler.com
"You must be
rdivilbiss
Governing Council Member
*
Offline Offline

Posts: 414



WWW
« Reply #6 on: February 10, 2008, 09:55:15 PM »

Off topic. Purse hook installed per request.
Logged

Rod
GrandSchtroumpf
Mentor

Offline Offline

Posts: 409



« Reply #7 on: February 15, 2008, 09:01:04 AM »

The problem in the original code is that your arrays are not built correctly.

You unset $args[0], then you create a new array that you pass to the recurse function:

>>    array(array($key => $value), $args)

This is wrong... the resulting array is not what you need.

It's an array with 2 entries:
    [ 0 ] : an array that contains your data.
    [ 1 ] : an array that contains your arguments.

What you really need is this:
    [ 0 ] : data
    [ 1 ] : arg 1
    [ 2 ] : arg 2
    [ 3 ] : arg 3
      ...
    [ n ] : arg n

You could fix it using "array_merge", but there is a much simpler solution:
Don't unset $args[0] and use "$args[0] = data".

Another small problem is that you forgot to pass "$keys" to your recursion call.
Bloody default argument values!!!  Use them wisely... or don't use them at all.

To simplify the code I also changed this:
            $new_data[$key] = (is_string($value)) ? call_user_func_array(...) : recurse(...);
To this:
            $new_data[$key] = recurse(...);

See fixed code here:
Code
Language: php (GeSHi-highlighted)
<pre>
<?php

function recurse($func, $args, $keys)
{
if (is_string($args[0]))
{
return call_user_func_array($func, $args);
}
else if (is_array($args[0]))
{
$data = $args[0];
$new_data = array();
foreach ($data as $key => $value)
{
if ($keys)
{
$args[0] = $key;
$key = call_user_func_array($func, $args);
}
$args[0] = $value;
$new_data[$key] = recurse($func, $args, $keys);
}
return $new_data;
}
}

function test($data, $pad, $pad2)
{

$data = strtoupper($data);
if ($pad) {
$data = '___' . $data . '___';
}
if ($pad2) {
$data = 'xxx' . $data . 'xxx';
}
return $data;

}

$array = 'mmm';
$array = array('bbb', 'ccc', array('ddd', 'eee' => 'ddd', array('fff')));
$array = recurse('test', array($array, true, true), true);
print_r($array);

?>
</pre>
« Last Edit: February 15, 2008, 09:16:56 AM by GrandSchtroumpf » Logged
Pages: [1]
« previous next »
    Jump to: