Divide results, add an add on count and put into JSON array

Discussion in 'PHP' started by scottlpool2003, Jan 10, 2014.

  1. #1
    I'm really struggling (always do with arrays).

    What I want to do is pull the latest 10 news stories, split them in 2, add an advert and then put them into a JSON array ready to send to an iPhone.

    So far I have this (messy, I know):

    
       $count = 0;
        foreach ($rows AS $row){ 
          $count++;
          //echo $row[id]."<br />";
            $result_array[] = $row[id];
          if ($count == 5){
            $count = 0;
            //echo "Advert<br />";
            $ad = array("newad.jpg");
            $array = array_merge($result_array, $ad);
    
        $message = $message = array(
        "Stories" => array (array(
            "success" => 'true',
            "rows" => $array
        )));
        echo json_encode($message);
          }
     
    PHP:
    Expected Output:
    
    {"Stories":[{"success":"true","rows":["964","963","960","959","958","newad.jpg","959","960","961","962","963"]}]}
    
    PHP:
    Output
    {"Stories":[{"success":"true","rows":["964","963","960","959","958","newad.jpg"]}]}{"Stories":[{"success":"true","rows":["964","963","960","959","958","957","956","955","954","952","newad.jpg"]}]}
    PHP:
    I can see I'm going wrong in the if ($count == 5) as that's where it's adding it as a new array rather than appending the existing array.

    If somebody could help me clean this up and outputting the expected result, that would be great!
     
    scottlpool2003, Jan 10, 2014 IP
  2. PoPSiCLe

    PoPSiCLe Illustrious Member

    Messages:
    4,623
    Likes Received:
    725
    Best Answers:
    152
    Trophy Points:
    470
    #2
    You're overcomplicating things. Here:
    
    <?php
       $rows = array(1,2,3,4,5,6,7,8,9,10);
       
       $count = 0;
       $result_array = array();
       foreach ($rows as $row) {
         $count++;
         $result_array[] = $row;
         if ($count == 5) {
           $result_array[] = 'newad.jpg';
         }
         $message = $message = array(
           "Stories" => array(
             "success" => 'true',
             "rows" => $result_array
             )
           );
       }
         echo json_encode($message);
    ?>
    
    PHP:
    outputs: {"Stories":{"success":"true","rows":[1,2,3,4,5,"newad.jpg",6,7,8,9,10]}}

    Make a note that I've changed the code above to work with the provided sample-array, hence you need to change $row to $row['id']; and perhaps make other adjustments
     
    PoPSiCLe, Jan 10, 2014 IP
  3. scottlpool2003

    scottlpool2003 Well-Known Member

    Messages:
    1,708
    Likes Received:
    49
    Best Answers:
    9
    Trophy Points:
    150
    #3
    Thanks, almost works as expected. I was using $row['id'] so I could see the data more easily. I do want the entire rows outputting.

    Quick one though, any reason you can think of why body would be returning null? Here is what I am seeing:

    Full code:

    
       $sth = $dbconn->prepare("
        SELECT * FROM `stories` INNER JOIN images ON stories.id = images.story_id WHERE cat_id =:catid ORDER BY stories.id DESC LIMIT 10
        ");
    
        $sth->execute(array(":catid"=> ''.$_GET[catid].''));
        $result_array = array();
        $rows = $sth->fetchAll(PDO::FETCH_ASSOC);
      $count = 0;
       $result_array = array();
       foreach ($rows as $row) {
         $count++;
         $result_array[] = $row;
         if ($count == 5) {
           $result_array[] = 'newad.jpg';
         }
         $message = $message = array(
           "Stories" => array(array(
             "success" => 'true',
             "rows" => $result_array
             )
        )
           );
       }
         echo json_encode($message);
    
    PHP:
     
    scottlpool2003, Jan 10, 2014 IP
  4. PoPSiCLe

    PoPSiCLe Illustrious Member

    Messages:
    4,623
    Likes Received:
    725
    Best Answers:
    152
    Trophy Points:
    470
    #4
    No, sorry - what should the "body" contain? Perhaps more of the tables have a "body" field? Without seeing the actual data in the database, it's almost impossible to discern what might be wrong.
     
    PoPSiCLe, Jan 10, 2014 IP
  5. scottlpool2003

    scottlpool2003 Well-Known Member

    Messages:
    1,708
    Likes Received:
    49
    Best Answers:
    9
    Trophy Points:
    150
    #5
    I had to print_r($result_array) in the JSON array rather than $result_array.

    Thanks for your help.
     
    scottlpool2003, Jan 10, 2014 IP
  6. scottlpool2003

    scottlpool2003 Well-Known Member

    Messages:
    1,708
    Likes Received:
    49
    Best Answers:
    9
    Trophy Points:
    150
    #6
    Nope, thought it had worked but it's outputting it as an array rather than JSON...

    EDIT
    ========
    I had to encode the row in UTF-8 before adding it to the JSON array. Final code:

        $sth = $dbconn->prepare("
        SELECT * FROM `stories` INNER JOIN images ON stories.id = images.story_id WHERE cat_id =:catid ORDER BY stories.id DESC LIMIT 10
        ");
    
        $sth->execute(array(":catid"=> ''.$_GET[catid].''));
        $result_array = array();
        $rows = $sth->fetchAll(PDO::FETCH_ASSOC);
       
      $count = 0;
       $result_array = array();
       foreach ($rows as $row) {
       
         $count++;
         $result_array[] = array_map('utf8_encode', $row);
        
         if ($count == 5) {
           $advert = base64_encode(file_get_contents('http://www.cheshireindependent.co.uk/app/images/ads/advert.gif'));
        
           $result_array['Advert'] = $advert;
       
         }
         $message = $message = array(
           "Stories" => array(array(
             "success" => 'true',
             "rows" => $result_array
             )
        )
           );
       }
         echo json_encode($message);
    PHP:
     
    Last edited: Jan 10, 2014
    scottlpool2003, Jan 10, 2014 IP
  7. ThePHPMaster

    ThePHPMaster Well-Known Member

    Messages:
    737
    Likes Received:
    52
    Best Answers:
    33
    Trophy Points:
    150
    #7
    I would use built in PHP to do the inner stuff. In regards to the array showing multiple times it is because you have the $message = .. in the actual loop.

    
        $sth = $dbconn->prepare("
           SELECT * FROM `stories` INNER JOIN images ON stories.id = images.story_id WHERE cat_id =:catid ORDER BY stories.id DESC LIMIT 10
         ");
    
        $sth->execute(array(":catid"=> ''.$_GET[catid].''));
        $result_array = array();
        $result_array = $sth->fetchAll(PDO::FETCH_ASSOC);  
    
        array_walk_recursive($result_array, 'utf8_encode'); 
    
        array_splice($result_array, 5, 0, array(base64_encode(file_get_contents('http://www.cheshireindependent.co.uk/app/images/ads/advert.gif'))));
    
        $message = array(
           "Stories" => array(
                array(
                    "success" => 'true',
                    "rows" => $result_array
                ),
            ),
        );
    
        echo json_encode($message);
    
    PHP:
     
    ThePHPMaster, Jan 10, 2014 IP
  8. scottlpool2003

    scottlpool2003 Well-Known Member

    Messages:
    1,708
    Likes Received:
    49
    Best Answers:
    9
    Trophy Points:
    150
    #8
    Thanks, looks a lot neater and would obviously take less memory but it outputs like so:

    {"Stories":[{"success":"true","rows":[""]}]}
    PHP:
     
    scottlpool2003, Jan 14, 2014 IP
  9. ThePHPMaster

    ThePHPMaster Well-Known Member

    Messages:
    737
    Likes Received:
    52
    Best Answers:
    33
    Trophy Points:
    150
    #9
    I haven't tested the code. Debug each step and see where the issue is.
     
    ThePHPMaster, Jan 14, 2014 IP
  10. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,999
    Best Answers:
    253
    Trophy Points:
    515
    #10
    You've got a LOT of extra variables and 'code for nothing' in there.

    $statement = $dbconn->prepare('
    	SELECT * FROM stories
    	INNER JOIN images
    		ON stories.id = images.story_id
    	WHERE cat_id = :catid
    	ORDER BY stories.id DESC
    	LIMIT 10
    ');
     
    $statement->execute([
    	':catid' => $_GET[catid]
    ]);
    
    $results = [];
    
    $count = 0;
    while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
    	$results[] = array_map('utf8_encode', $row);
    	if ((++$count) == 5) $results['Advert'] = base64_encode(
    		file_get_contents('http://www.cheshireindependent.co.uk/app/images/ads/advert.gif')
    	);
    }
    
    echo json_encode([
    	'Stories' => [
    		'success' => 'true',
    		'rows' => $results
    	]
    ]);
    Code (markup):
    Though I'd REALLY REALLY NOT send the contents of the gif for the advert, waste of bandwidth if it gets sent more than once -- why aren't you just sending it's URL?
     
    deathshadow, Jan 16, 2014 IP
  11. scottlpool2003

    scottlpool2003 Well-Known Member

    Messages:
    1,708
    Likes Received:
    49
    Best Answers:
    9
    Trophy Points:
    150
    #11
    Thanks, will test that and let you know. As per the image, yep I'd already changed that to only have the URL.
     
    scottlpool2003, Jan 16, 2014 IP
  12. scottlpool2003

    scottlpool2003 Well-Known Member

    Messages:
    1,708
    Likes Received:
    49
    Best Answers:
    9
    Trophy Points:
    150
    #12
    I've just been testing it, and running into errors. Is the above running on PHP5.4?
     
    scottlpool2003, Jan 17, 2014 IP