개발 Q&A

제목 php 배열 관련 질문입니다!
글쓴이 워크3카오스 작성시각 2013/07/08 15:57:59
댓글 : 6 추천 : 0 스크랩 : 0 조회수 : 15168   RSS
    {"title": "Item 1"}, 
    {"title": "Folder 2", "isFolder": true, "key": "folder2", 
        "children": [ 
            {"title": "Sub-item 2.1"}, 
            {"title": "Sub-item 2.2",  "children": [ 
                                            {"title": "Sub-item 2.1.1.1"}, 
                                            {"title": "Sub-item 2.1.2.2"}, 
                                            {"title": "Sub-item 2.1.1.3"}, 
                                            {"title": "Sub-item 2.1.2.4"} 
                                                                                
                                              ] 
                        }, 
                        {"title": "Sub-item 2.1.4"} 
                           ] 
}
]

이런 형태의 배열로 뽑아낼려고 하는데 
다차원 배열 형식이면서 하위 노드가 있는 경우에만 데이터를 추가로 줘야 하다보니 ...

생각한 의도대로 저런 배열 형태가 나오질 않네요;;

아래와 같은 형태로 했을 경우에는 원하는 형태로 나오지만 자식 노드가 있는 만큼 foreach문을 계속적으로 추가해줘야 해서 문제가 되더라구요 ..
( 소스가 길어도 상관은없는데.. 위 형태처럼 자동적으로 뽑아낼수있는 방법이 없을까요 ? .... 
(  php.net에서 배열 쪽 함수를 보고, phpschool에 질문도 올려봤으나 마땅히 답이 생각나지 않아 질문해봅니다 )
 
public function tree($id = '', $return=false)
{
$this->db->select('cp.*, (SELECT COUNT(*) FROM cp A WHERE A.low_id = cp.id) AS sub');
$this->db->from(cp);  
    if($id)     $this->db->where('co.low_id', $id);
    else          $this->db->where('cp.low_id', null);
   $query = $this->db->get();
   if($return) return $query->result_array();
    $cate= $query->result_array();

    foreach($cate as $key => $data)
    {
      $test[$key]['title']   = $data['name'];
      $test[$key]['pum_id']  = $data['id'];
      $test[$key]['isFolder']  = true;
      
      if($data['sub'] > 0)
      {
        $category = $this->tree($data['id'], true);
        foreach($category as $key2 => $second)
        {
          $test[$key]['children'][$key2]['title']    = $second['name'];
          $test[$key]['children'][$key2]['pum_id']   = $second['id'];
                                         .....
     }    
    }



 다음글 linux centos 로그를 삭제하라고 하는데.. (5)
 이전글 tank_auth 사용을 해봤는데.. (5)

댓글

/ 2013/07/08 17:37:17 / 추천 0
배열이라고 하고 json으로 쓰셔서 헷갈렸습니다 ㄷㄷ;

오늘 소스를 너무 많이 봤더니 머리가 아파서 짜드리긴 좀 힘들고;

힌트만 먼저 드리자면

거의 다 해두신거 같은데 ...

재귀함수 형태로 작성을 하시면 좋을 것 같아요

비슷한 예제로는 php로 특정폴더와 하위폴더 (파일포함) 전체 삭제 로직이 될 것 같네요;

워크3카오스 / 2013/07/08 17:55:30 / 추천 0
키 님 답변 감사합니다 
제가 질문을 하는데 실수를 했었네요;

저도 같은 형태로 재귀함수 호출해서 데이터를 뽑아내려고 했었는데요

데이터를 가져오는 방법에는 문제가 없지만 데이터를 넣어줘야 할 부분에
추가적으로 계속해서 ['children'][$key2] 이런 조건이 붙어서 문제가 되었습니다..

반복문을 통해서 갖다 붙일수도있는데
[$key2] , [$key3] 이 부분은 each문을 한번 씩 더 돌면서 해당 변수를 가져오는 부분이라 어떻게 처리를 해줘야 할지 모르겠네요 
..아니면 제가 지금 착각하고있는건지, 문제를 잘못 이해하고있는건지.. 머리가 잘 안돌아가네요 ;;;;


말씀해주신 php 특정폴더 하위폴더 삭제 로직은 한번 찾아보도록 하겠습니다.
답변 감사드립니다.

/ 2013/07/08 18:05:15 / 추천 0
음... 그냥 짬내서 잠깐 만들어봤는데 

ci상에서 돌려보지 않고 에딧플러스에서만 구현했습니다.

db 구조도 정확하게 알수 없어서 

샘플 코드만 짜봤습니다.

for 부분과 몇군데는 혹시 에러가 날지 모릅니다 로직만 참고하시면 좋을 듯 합니다.




public function tree($id = '')
{
 $rtn=array();

 $this->db->select('cp.*, (SELECT COUNT(*) FROM cp A WHERE A.low_id = cp.id) AS sub');
 $this->db->from('cp');  

    if($id)     $this->db->where('co.low_id', $id);
    else          $this->db->where('cp.low_id', null);

    $query = $this->db->get();
   
    for($i=0;$data=$query ->result_array();$i++)
    {
   
      if($data['title'])$rtn[$i]['title']  = $data['title'];
   if($data['id'])$rtn[$i]['pum_id']  = $data['id'];
   if($data['isFolder'])$rtn[$i]['isFolder']  =true;
      
      if($data['sub'] > 0)
     {     
    $rtn[$i]['children']=$this->tree($data['id']);
     }    

 return $rtn;
  }


  echo json_encode(tree());

워크3카오스 / 2013/07/08 18:22:58 / 추천 0
 답변 감사합니다
참고해서 해보도록하겠습니다.
워크3카오스 / 2013/07/09 10:51:01 / 추천 0
말씀해주신 방법으로 돌려보고 테스트를 해봤는데 딱 첫번째 값만 가져오네요 ;; 
public function tree_test($id = '', $return=false)
 {
  $rtn = array();
  $this->db->select('CP.*, (SELECT COUNT(*) FROM TABLE A WHERE A.parent_ID = CP.ID) AS SUBCNT');
  $this->db->from($this->table_name['CP']);
  
  if($id)   $this->db->where('CP.parent_ID', $id);
  else   $this->db->where('CP.parent_ID', null);
  
  $query = $this->db->get();
  
  if($return) return $query->result_array();
  
  for($i=0; $data=$query->result_array(); $i++)
  {
   if(isset($data[$i]['ID']))
   {
    $rtn[$i]['title']     = $data[$i]['NAME'];
    $rtn[$i]['pum_id']    = $data[$i]['ID'];
    $rtn[$i]['isFolder']  = true;
    
    if($data[$i]['SUBCNT'] > 0)
    {    
     $rtn[$i]['children'] = $this->tree_test($data[$i]['ID'], true);
    }
   }
   else
   {   
     return $rtn;
   }
   
  }
}
말씀해주신 부분이, $data를 for문 만큼 돌리는데, sub가 있을 경우 children을 포함시켜되 그 포함시켜주는 데이터는 다시 재 쿼리해서 가져온다 . 이렇게 생각하고 수정도조금씩해보면서 2번째 children 값 까지 밖에 가져오지 못하네요

아... true 대신에 false로 잡아주고 계속 for문을 돌게하니 쿼리가 돌아가네요 .. 조언해주신 방법으로 테스트하다보니 뒷걸음치다 얼떨결에 답에 근접했네요 감사합니다...^^;;;;

다시 재 쿼리해서 가져 올 때 문제가 있지 않을까 생각이 되는데 어디가 틀렸는지 알 수가 없네요;;

/ 2013/07/09 23:04:36 / 추천 0
워크3카오스 // 

제가 생각했던 것과는 좀 다르게 구현이 된 것 같은데... 음

제가 위에 소스로 봤을땐 

$return 의 필요성.

else { return $rtn} 의 위치 (문법상 안맞아보입니다; 위 소스가 돌아가던가요?;)

$data[$i]['field'] << ???;; 제가 생각했던 것은 $data['field']가 정상입니다


이렇게 3가지가 의문점이 드네요.


첫번째 값만 가져온다고 하셨던 것은.. 음. 

for문이 제가 직접 돌려본게 아니라 예전에 쓰이던 

for($i=0;$data=mysql_fetch_array($result);$i++){
~~~~
}


이런 문법이 생각나서 작성해본건데 ci에서 동작하는지 테스트는 해보지 않았습니다. 

요즘엔 foreach로 다 처리하다보니;