PHP recursive fonksiyon + referans = baş ağrısı array

3 Cevap php

I have an interesting problem. The basis of the problem is that my last iteration of an array reference doesn't seem to "stick," if you will. A little context: I've devised a very simple data structure for page heirarchy that looks like this:

, 1,2,3>, 4>, 5,6,7 <<, 8

Çeviri: sataşmak lider virgül unutun. Sayfa 1, 2, 3, ve 8, üst-seviye sayfa id olan 4 ('>' derin bir seviyeye taşımak anlamına gelir), 3 alt sayfa ve 5, 6, ve 7, 4 alt sayfalar.

Daha okunabilir format bu gibi görünecektir:

1
2
3
-- 4
-- -- 5
-- -- 6
-- -- 7
8

Ben bu şekilde yapıyorum, neden bana sormayın. Henüz bir web formu üzerinden javascript ve ilanıyla birlikte yapıyı üreten basit bir yol ile geldi değil.

Sorun her şeyin özyinelemeli işlev boyunca harika gidiyor, ama geri benim Arayan fonksiyonu sayfa 8. kaybetmek olduğunu. Ben özyineleme, değişken referanslar, ve değişken kapsamı bazı eleman yanılmıyorsam, ve bu oldukça bulmaca dönüşmüştür şüpheli.

(Fonksiyonunun son çağrı içinde sadece iyi çalışıyor) Beklenen Çıktı:

Array
(
[1] => Array
    (
    )

[2] => Array
    (
    )

[3] => Array
    (
        [4] => Array
            (
                [5] => Array
                    (
                    )

                [6] => Array
                    (
                    )

                [7] => Array
                    (
                    )

            )

    )

[8] => Array
    (
    )

)

(Döngü dışında) Gerçek Çıkış:

Array
(
[1] => Array
    (
    )

[2] => Array
    (
    )

[3] => Array
    (
        [4] => Array
            (
                [5] => Array
                    (
                    )

                [6] => Array
                    (
                    )

                [7] => Array
                    (
                    )

            )

    )

)

Herhangi bir düşünce?

[EDIT]: Ben artık self :: referanslar bir çift kaldırıldı ...

KOD:

<?php
// recursive string in this format: (,\d+)*[>|<]?
//   ,      = leading comma
//   n,n+1  = comma-delimited list of page_ids
//   >      = indicates the next step in our depth-first approach
//   <      = indicates we're done with that set of children. back it up.
function parse_page_orders($page_orders, &$cur_page, &$trail)
{
	// #1 matches our comma-led, comma-delimited list of page id's
	// #2 matches our next step--forward or backward
	preg_match('/([,\d+]*)([>|<])?/', $page_orders, $matches);

	// remove this section of the page_orders variable so we can get on with our lives
	$page_orders = str_replace($matches[0], '', $page_orders);

	// #1: get the list of page ids and add it to the current page item
	$p = explode(',', $matches[1]);
	// start at 1 to skip the empty element at the beginning
	for ($i=1; $i<count($p); $i++)
	{
		$cur_page[$p[$i]] = array();
	}
	// #2: determine our next step
	if (isset($matches[2]))
	{
		if ($matches[2] == '>')
		{
			$trail[] = &$cur_page;
			parse_page_orders($page_orders, $cur_page[end($p)], $trail);
		}
		elseif ($matches[2] == '<' && count($trail)>0)
		{
			parse_page_orders($page_orders, array_pop($trail), $trail);
		}
	}
	else
	{
		// we're done. this should be our result.
		print_r($cur_page);	
	}
}
$pages = array();
$trail = array();
$page_orders = ',1,2,3>,4>,5,6,7<<,8';
parse_page_orders($page_orders, $pages, $trail);
print_r($pages);

?>

3 Cevap

durumda "sizin" biçiminde dizesini ayrıştırmak nasıl ilgileniyoruz:

	class Parser {

		function run($str) {
			preg_match_all('~(\d+)|[<>]~', $str, $a);
			$this->a = $a[0];
			return $this->expr();
		}

		function expr() {
			$q = array();
			while(1) {
				if(!count($this->a)) return $q;
				$sym = array_shift($this->a);
				if($sym == '<') return $q;
				if($sym == '>')
					$q[count($q) - 1]['children'] = $this->expr();
				else
					$q[] = array('id' => $sym);
			}
		}
	}


	$a = "1,2,3>4,>5,6,7<<,8>9,10,>11<,12,<,13,14";
	$p = new Parser;
	$result = $p->run($a);
	print_r($result);

Eğer php javascript bir veri yapısı göndermek istiyorsanız, o zaman JSON deneyin. Bu javascript böyle bir şey olacaktır:

var obj = {1:[], 
           2:[], 
           3:{
              4:{
                 5:[], 
                 6:[], 
                 7:[]
                }
             }, 
           8:[]};

var json = JSON.stringify(obj);

//Now send it to the server as a string

Bu $ json şimdi javascript oluşturulan dize var varsayarak, sunucu üzerindeki tüm ihtiyaç vardır

<?php    
$arr = json_decode($strng, true);
print_r($arr);
?>

Eğer daha yüksek bir düzeyde (bir

Mantık böyle bir şey olmalı:

//parse page order string or its single level
function parse_page_orders(&$page_orders)
{  
  $result=array();
  while($page_orders)
  {
    $token=nextToken($page_orders);
    if ($token=='>') //iterate deeper on >
    {
       $result[]=parse_page_orders($page_orders);
       continue;
    }
    if ($token=='<') 
       return $result;
    if (is_numeric($token))
       $result[]=parseInt($token);
  }
return $result;
}

function nextToken(&$page_orders)
{
  if(preg_match('/(\d+)/'),$page_orders,$m)
  {
     $page_orders=substr($page_orders,strlen($m[1]));
     return parseInt($m[1]);
  }
  else
  {
    $result=$page_orders{0};
    $page_orders=substr($page_orders,1);
    return $result;
  }
}