来自php数组的json_encode:如何调整我的php以便我的数组是正确的?

问题描述:

I am trying to create a php array from posted values and then json_encode to achieve this:

[{"network_type":"facebook","network_url":"fb.com/name"},{"network_type":"twitter","network_url":"@name"},{"network_type":"instagram","network_url":"#name"}]

which after json_decode looks like:

array(
 [0] => stdClass(

 network_type = 'facebook'
 network_url = 'fb.com/name'
 )

 [1] => stdClass(

 network_type = 'twitter'
 network_url = '@name'
 )

 [2] => stdClass(

 network_type = 'instagram'
 network_url = '#name'
 )
)

My php looks like this:

$social_data = array(

          'network_type'    => $this->input->post('network_type'),
          'network_url'     => $this->input->post('network_url')
    );

and so the array is not grouped the way I want it, but rather by the field name:

array(
['network_type'] => array(
  [0] => 'facebook'
  [1] => 'twitter'
  [2] => 'instagram'
)
['network_url'] => array(
  [0] => 'fb.com/name'
  [1] => '@name'
  [2] => '#name'
)

and therefore the result of the json_encode isn't grouped how I want it:

 {"network_type":["facebook","twitter","instagram"],"network_url":["fb.com/name","@name","#name"]}

)

So the question is...how do I adjust my php so the array is correct?

--- here's the input fields:

<?php
        foreach ($social as $key => $value) {?>
         <p>
              <label for="network_type"><input type="text" size="20" name="network_type[]" value="<?php echo $value -> network_type; ?>" placeholder="Social Network" /></label>
              <label for="network_url"><input type="text" size="20" name="network_url[]" value="<?php echo $value -> network_url; ?>" placeholder="URL or Handle" /></label>
              <a class="remNetwork" href="#">Remove</a>
          </p>
      <?php } ?>

----latest update: this is sooooo close!----- Ok, for some reason (probably me botching things one way or another), both suggested methods below didn't quite get me there....but, a mix of both methods has gotten me close:

This if/loop/array setup:

 $network_type    = (array)$this->input->post('network_type', true);
$network_url     = (array)$this->input->post('network_url', true);
$social_data = array();


if (($counter = count($network_type)) == count($network_url)){
for($i = 0;$i < $counter; $i++) {
    $social_data[$i] = array(
            'network_type'    => $this->input->post('network_type[$i]'),
            'network_url'     => $this->input->post('network_url[$i]'),
        );
  }
}

paired with this input loop:

<?php
        foreach ($social as $key => $value) {
      ?>
         <p>
              <label for="network_type"><input type="text" size="20" name="network_type[]" value="<?php echo $value -> network_type; ?>" placeholder="Social Network" /></label>
              <label for="network_url"><input type="text" size="20" name="network_url[]" value="<?php echo $value -> network_url; ?>" placeholder="URL or Handle" /></label>
              <a class="remNetwork" href="#">Remove</a>
          </p>
      <?php } ?>

is yielding the following:

array(
  [0] =>  array(
    ['network_type'] => FALSE
    ['network_url'] => FALSE
  )
  [1] => array(
    ['network_type'] => FALSE
    ['network_url'] => FALSE
  )
  [2] => array(
    ['network_type'] => FALSE
    ['network_url'] => FALSE
  )
)

So, I think if I can figure out why these values are false, then we've done it! Thanks and appreciation for your patience and help in advance...

-- update again ---- To my dismay, I've left out a piece that's perhaps critical...the coffee script that's dynamically creating the form fields when there's more than one social:

$ ->


socialDiv = $("#social")
  i = $("#social p").size() + 1
  index = 0
  $("#addNetwork").click ->
$("<p><label for=\"network_type[]\"><input type=\"text\" id=\"network_type[]\" size=\"20\" name=\"network_type[]\" value=\"\" placeholder=\"Social Network\" /></label><label for=\"network_url[]\"><input type=\"text\" id=\"network_url[]\" size=\"20\" name=\"network_url[]\" value=\"\" placeholder=\"URL or Handle\" /></label> <a href=\"#\" class=\"remNetwork\">Remove</a></p>").appendTo socialDiv
i++
false
$(document).on "click", ".remNetwork", ->
      #$(".remNetwork").bind "click", ->
        if i > 1
          $(this).parent("p").remove()
          i--
        false

In your example, i can asume that network_type and network_url are inputs like:
<input type="text" name="network_type[]" /> and <input type="text" name="network_url[]" />

so in order to accomplish what you want you would:

<?php
$networkType = (array)$this->input->post('network_type', true);
$networkUrl = (array)$this->input->post('network_url', true);

$networkData = array();
if (($counter = count($networkType)) == count($networkUrl)) {
    for ($i = 0; $i < $counter; ++$i) {
        $networkData[] = array(
            'network_type' => $networkType[$i],
            'network_url' => $networkUrl[$i]
        );
    }
}
?>

and should give you the desired json.
However, this approach is a bit clunky and unreliable.

Instead, i would define the input fields like:

<input type="text" name="network[0][network_type]" /> and <input type="text" name="network[0][network_url]" />

<input type="text" name="network[1][network_type]" /> and <input type="text" name="network[1][network_url]" />

and i would generate the php array like:

<?php
$networkData = (array)$this->input->post('network', true);
?>

Just my two cents :)

L.E:
To make it detailed and create the std objects from your array, you would:

$networkData = array();
if (($counter = count($networkType)) == count($networkUrl)) {
    for ($i = 0; $i < $counter; ++$i) {
        $obj = new StdClass();
        $obj->network_type = $networkType[$i];
        $obj->network_url = $networkUrl[$i];
        $networkData[] = $obj;
    }
}
print_r($networkData);

You can use a for loop to iterate through as you feed them into the $social_data array. It would be

for($i = 0;$i < $items.length;$i++) {
    $social_data[$i] = array(
            'network_type'    => $this->input->post('network_type[$i]'),
            'network_url'     => $this->input->post('network_url[$i]'),
        );

The resulting array will look like:

$social_data[0] -> 
    'network_type' => 'facebook',
    'network_url' => 'fbook.com/user'
$social_data[1] ->
     ...etc

I'm not totally sure what context you're getting the network_type and url but they will both be arrays and looping through for each individual value is what to do. Without the rest of the code it's hard to get much more specific but hopefully this will point you in the right direction.