Jump to content

[SOLVED] Problems Unserializing a non standard serialized array


lachild

Recommended Posts

Hello everyone.  I have been working on this problem for hours with no success.

 

I have a serialized array that I was givin in a text document formated as such:

 

value1 AND value2 AND (value3 OR value4 AND (value5 or value6) AND value7)

 

What needs to happen is this needs to translate into the following:

 

$newArray = array (
                          'value1' => array (
                               'value2' => array (
                                   'value3' => array (
                                       'value5' => array ('value7'),
                                       'value6' => array ('value7'),
                                       ),
                                   'value4' => array (
                                       'value5' => array ('value7'),
                                       'value6' => array ('value7'),
                                       ),
                                   },
                               },
                          };

 

I thought I'd be able to do a preg_match_all, process the inner () and then the outter () but the logic escapes me.

 

There are over 30,000 of these statements so processing them manually would simply take too long.

 

Any direction would be appreciated.

 

Thanks in advance.

LaChild

Link to comment
Share on other sites

try

<?php
$a = 'value1 AND value2 AND (value3 OR value4 AND (value5 OR value6) AND value7)';
$a = str_replace(array('(',')'), '', $a);
$b = explode(' AND ', $a);
$o = '';
for ($i = count($b)-1; $i >= 0; $i--) {
$tmp = explode(' OR ', $b[$i]);
if ($o){
	$q = $o;
	$o = array();
	foreach ($tmp as $x) $o[$x] = $q;

} else $o = $tmp;
}
print_r($o);
?>

Link to comment
Share on other sites

Sasa,

 

Thank you so much for the help.  And that almost works, except that it really doesn't take the "()" into account, which is where my problem is.  Other then that it works great.  But something like this "(value1 and value2) OR (value3 and value4) will not come out correctly.

 

This is the problem I keep running into.. Fix one and it breaks another set of attributes.

 

If I could figure out how to take and process the () correctly (that may or maynot have inner brackets in inner brackets etc) it would greatly help the situation.

Link to comment
Share on other sites

Ok I was able to use a preg_split to get the needed result... Now its just a matter of peicing the peices together.  I have an idea but thought someone might no some shortcuts to peice this together correctly.

 

Here's the split

<?php
$a = 'value1 OR ((value2 AND value3) OR value4 AND (value5 OR value6)) OR (value7 AND value8) AND value9';
$a = preg_split('/[\((.*?)\)]{1,2}/',$a);

foreach ($a as $k => $v)
{
$a[$k] = trim($v);
}

print_r ($a);

?>

 

(I omitted the code I'm working on because it

  A) doesn't work and

  B) looks really sloppy

lol )

 

At any rate the result for ('value1 OR ((value2 AND value3) OR value4 AND (value5 OR value6)) OR (value7 AND value8) AND value9') now looks like the following:

 

Array
(
    [0] => value1 OR
    [1] => value2 AND value3
    [2] => OR value4 AND
    [3] => value5 OR value6
    [4] => OR
    [5] => value7 AND value8
    [6] => AND value9
)

 

and the following

$a = '(value1 AND value2) OR (value3 OR value4) AND (value5 AND value6) OR (value7 OR (value8 AND value10)) AND value9';

 

looks like

 

Array
(
    [0] => 
    [1] => value1 AND value2
    [2] => OR
    [3] => value3 OR value4
    [4] => AND
    [5] => value5 AND value6
    [6] => OR
    [7] => value7 OR
    [8] => value8 AND value10
    [9] => AND value9
)

 

Thanks again for any help

Link to comment
Share on other sites

try

<?php
function uns1($a) {
$b = explode(' AND ', $a);
$o = '';
for ($i = count($b)-1; $i >= 0; $i--) {
	$tmp = explode(' OR ', $b[$i]);
	if ($o){
		$q = $o;
		$o = array();
		foreach ($tmp as $x) $o[$x] = $q;
	} else $o = (count($tmp) == 1) ? $tmp[0] : $tmp;
}
return $o;
}

function aa ($a, $b) {
foreach ($a as $k => $v) {
	if (is_array($v)) { 
		//unset($a[$k]);
		$a[$k]=aa($v, $b);
	} else { 
		//unset($a[$v]);
		unset($a[$k]);
		if (is_array($b) && count($b) == 1) $b=$b[0];
		$a[$v] = $b;

	}
} 
return $a;
}

function uns2($a) {
$j=-1;
$i = strpos($a,'(');
if ($i === false) return uns1($a);
else { 
	$count=1;
	$j = $i;
	while ($count > 0) {
		$i++;
		if ($a[$i] == '(') $count++;
		if ($a[$i] == ')') $count--;
	} 
	if ($j == 0) {
		$a1 = trim(substr($a, 1, $i-1));
		$o1 = trim(substr($a, $i+1, 4));
		$a2 = trim(substr($a, $i+5));
		$a1 = uns2($a1);
		if (!is_array($a1)) $a1=array($a1);
		if ($a2) $a2 = uns2($a2); //else $a2 =array();
		if (!is_array($a2)) $a2=array($a2);
		if ($o1 == 'AND') $out = aa($a1,$a2);
		else {
			if ($o1=='OR') $out = array_merge($a1,$a2);
			else $out = $a1;
		}
	} elseif ($j>0) {
		$a1 = trim(substr($a, 0, $j-4));
		$o1 = trim(substr($a, $j-4,4));
		$a2 = trim(substr($a,$j));
		$a1 = uns2($a1);
		if (!is_array($a1)) $a1=array($a1);
		$a2 = uns2($a2);
		if (!is_array($a2)) $a1=array($a2);
		if ($o1 == 'AND') $out = aa($a1,$a2);
		else {
			if ($o1=='OR') $out = array_merge($a1,$a2);
			else $out = $a1;
		}
	}
}
return $out;
}

$d = '(as OR df)';
$b='value1 AND value2 OR (value3 AND value4)';
$a = '(value1 AND value3) OR value4 AND (value5 OR value6) AND value7';
$c = 'value1 AND (value3 OR value4 AND (value5 OR value6) AND value7)';

$x = uns2($a);
print_r($x);

echo "\n\n";
$x = uns2($c);
print_r($x);
?>

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.