在CodeIgniter中检索JSON POST数据

15

我一直在尝试从我的PHP文件中检索JSON数据,但这让我很困扰。这是我的代码

我VIEW中的代码:

var productDetails = {'id':ISBNNumber,'qty':finalqty,'price':finalprice,'name':bookTitle};

        var base_url = '<?php echo site_url() ?>';
        $.ajax({
            url: "<?php echo base_url() ?>index.php/user/Add_to_cart/addProductsToCart",
            type: 'POST',
            data:productDetails,
            dataType:'JSON',
        });

尝试在我的控制器中检索:

echo $this->input->post("productDetails");

无输出。

以下是我的标题:

Remote Address:[::1]:80
Request URL:http://localhost/CI/index.php/user/Add_to_cart/addProductsToCart
Request Method:POST
Status Code:200 OK
Request Headersview source
Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8,fr;q=0.6
Connection:keep-alive
Content-Length:52
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Cookie:ci_session=3E5SPro57IrJJkjs2feMNlmMrTqEXrTNN8UyEfleeothNnHwNxuCZDSx4a7cJZGjj7fyr2KLpj%2BPNJeGRSzSPVmcFHVEdhSk4D47ziOl4eZcTUAZlQrWa3EYIeQJVWxMpiGZS26MEfbSXNmfel9e8TcsJTreZHipvfisrJovbXEAW4Uv%2BwrJRep1KCi1MMaDCVJb9UEinRVcDtYe%2F86jhn7kOj4kraVmVzx%2FsOaO0rAxLyAUtez%2Feaa4zBwpN3Td153sAoIb3WxVHoEj2oKyH5prVHigbIhIBR6XZqjBkM6hjBuoD2OSZ2wgLbp9DEENMoqui4WYyHROBuS2DYiJajblcS0KiFga5k%2FQOODvE7p6n%2BozN5ciDliVjJ4PnJ5PD1GaPEmec5%2FbQSlOHYWZk%2F2Blzw3Nw0EtLL7wKDzzQY%3Df645c36bb3548eb8de915b73f8763d97a47783ce
Host:localhost
Origin:http://localhost
Referer:http://localhost/CI/index.php/user/view_available_books/viewAvailableBooks/5
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36
X-Requested-With:XMLHttpRequest
**Form Dataview** sourceview URL encoded
id:234
qty:1
price:0.00
name:dasdadsd2q3e!@!@@

我在开发者工具中能看到的响应:

    Array
(
    [id] => 234
    [qty] => 1
    [price] => 0.00
    [name] => dasdadsd2q3e!@!@@
)

但在浏览器中,输出为空。我已经尝试解决了4个小时以上,但徒劳无功。

print_r($_POST); // outputs nothing
echo $data = file_get_contents('php://input'); //outputs nothing
echo $id    = $this->input->post('productDetails');// outputs nothing

我的视角代码:

<script>
    $('#addtoCart').on('click',function(event){
        event.preventDefault();
        $(this).attr('disabled',"disabled");
        finalprice = $.trim($('#price').val());
        finalqty = $.trim($('#quantity').val());

        var productDetails = JSON.stringify({'id':ISBNNumber,'qty':finalqty,'price':finalprice,'name':bookTitle});

        var base_url = '<?php echo site_url() ?>';
        // console.log($);
        $.ajax({
            url: "<?php echo base_url() ?>index.php/user/Add_to_cart/addProductsToCart",
            type: 'POST',
            contentType: "application/json; charset=utf-8",
            data:productDetails,
            dataType:'html',
        });


    });
</script>

控制器代码:

function addProductsToCart(){
        var_dump(json_decode(file_get_contents("php://input")));
        print_r($_POST);
        // $data = json_decode($_POST["productDetails"]);
        // var_dump($data);
        // echo $data = file_get_contents('php://input');
// print_r(json_decode($data));
        // $id    = $this->input->post('id');
        // $qty   = $this

    }

你做错的两件事情:1. data:{productDetails:productDetails},2. $data = json_decode($_POST["productDetails"]); - kamlesh.bar
你能展示一下当 $data 变量中获取到数据后,你想要做什么的代码吗?另外,你需要返回或者输出一些东西,以便从控制器中获取数据并使用 jQuery 进行处理。 - kamlesh.bar
请查看上面的代码...视图和控制器代码...控制器中什么都不起作用。 - Abhinav
让我们在聊天中继续这个讨论。链接 - kamlesh.bar
问题在于 CI 不知道如何将 JSON 处理成 $this->input->post()。你需要手动处理它。请查看下面的答案以获取解释。 - jimasun
显示剩余3条评论
7个回答

31
TLDR: 使用 $this->input->raw_input_stream 获取数据并手动解码。
我遇到了同样的问题。CodeIgniter 不知道如何获取 JSON 数据。一开始我认为这是编码的问题,因为我使用的是 fetch.js 而不是 jQuery。无论我尝试什么,都没有收到任何东西。 $_POST$this->input->post() 也都为空。以下是我如何解决这个问题的方法。
发送请求(这里显示为对象属性,因为你的 js 库可能不同):
method: 'POST',
headers: {
  'Accept': 'application/json',
  'Content-Type': 'application/json'
},
body: JSON.stringify({
  ready: 'ready'
})

节点(Node):我已经将类型为object的数据编码为json格式。当你设置dataType: 'JSON'选项时,jQuery会自动完成这个过程。

CodeIgniter(在我这里是3.1版本):

$stream_clean = $this->security->xss_clean($this->input->raw_input_stream);
$request = json_decode($stream_clean);
$ready = $request->ready;

注意:您需要清理$this->input->raw_input_stream。如果不使用$this->input->post(),则意味着您需要手动清理流(CodeIgniter不会自动执行此操作)。

至于响应:

$response = json_encode($request);
header('Content-Type: application/json');
echo $response;

或者您可以这样做:

echo $stream_clean;
注意:设置header('Content-Type: application/json')并不是必需的,但我认为这样做是一个好习惯。请求已经设置了'Accept': 'application/json'头部。

我们可以使用$this->input->input_stream(null, true)来代替通过$this->security->xss_clean()传递值,并将第二个参数设置为true以进行XSS过滤。 - Deepesh Kumar

12

我曾经遇到过同样的问题,但是我找到了解决方案。

这是我发送的Json代码:[{"name":"JOSE ANGEL", "lastname":"Ramirez"}]

$data = json_decode(file_get_contents('php://input'), true);
echo json_encode($data);

这段代码已经测试过,结果为[{"name":"JOSE ANGEL","lastname":"Ramirez"}]


7
尽管OP似乎很满意,但所选的答案并没有告诉我们原因和真正的解决方案。(顺便说一句,那个post_array实际上不是一个数组,而是一个对象) @jimasun的答案方法正确。我只想澄清一下,并提供一个CI之外的解决方案。

所以问题的原因是;

不是CI或PHP的问题,而是您的服务器不知道如何处理具有application/json内容类型的请求。因此,您将没有$_POST数据。PHP与此无关。阅读更多信息:使用PHP读取JSON POST

解决方案是;

要么不要将请求发送为application/json,要么处理请求正文以获取post数据。

对于CI,@jimasun的答案是精确的方法。

您还可以像这样使用纯PHP获取请求正文。

$json_request_body = file_get_contents('php://input');

3

我在CI中进行Ajax调用的一般方法:

JS:

post_array =
{
    "myvar" : "value1",
    "myvar2": "value2"
} 

$.post(baseUrl + "/AjaxController/my_function", post_array,
    function(data)
    {
        var res = jQuery.parseJSON(data);
        alert(res.property);
    }  

控制器:

public function my_function()
{
    $myvar = $this->input->post('myvar');
    $myvar2 = $this->input->post('myvar2'); 

    //Stuff

    echo json_encode($myobject);
}

把这些数据回显或放在视图文件的表格中怎么样?我该怎么做,@AdrienXL?我的JavaScript成功函数会是什么样子? - Eli
$myobject来自哪里? - logic-unit
@logic-unit 是你根据 //Stuff 部分需要完成的任务所构建的对象。 - AdrienXL
1
这大致是他所做的,但这个答案没有解决问题。在 OP 的问题中,需要使用 POST 获取 JSON。你的答案不透明,因为实际上在你的代码中,CI 没有将请求处理为 JSONjQuery 在过程中修改了请求负载到另一种格式!如果你需要按照操作系统所述使用 JSON,请查看我的答案以获取完整的解释。 - jimasun
1
我一点头绪都没有...不知道楼主能否告诉我们这个答案对他/她有什么帮助。 - Erdinç Çorbacı

2

你只有自己的答案。

print_r($_POST);

返回:

Array
(
    [id] => 234
    [qty] => 1
    [price] => 0.00
    [name] => dasdadsd2q3e!@!@@
)

那么你该如何获取:echo $id = $this->input->post('productDetails');

你可以通过以下代码获取 id:echo $id = $this->input->post('id');


那个结果数组只在我点击结果选项卡时才显示在开发工具中,而不是在那个页面上。 - Abhinav
print_r($_POST); 你必须写对了 PHP 的代码吗? - Rana Soyab
如果$_POST有值,那么$this->input->post()也将具有相同的值。 - Rana Soyab
你没有理解,我可以在开发者工具的预览选项卡中看到输出,但无法在该页面中检索它...我不知道为什么!!这就是我发布这个问题的原因! - Abhinav
@RanaSoyab,问题是$_POST也是空的。正如jimasun所描述的那样,CI不知道如何处理具有application/json内容类型的请求。 - Erdinç Çorbacı

0

以下解决方案适用于我 -

Ajax -

$.ajax({
        url: "AJAX_URL_HERE", 
        type: "POST",
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify({ msg: msg, sendmsg: 1, stdId: stdId }),
        success: function (result) {
            // when call is sucessfull
        },
        error: function (err) {
        // check the err for error details
        }
      }); // ajax call closing

在控制器中 -

$post_data = json_decode(file_get_contents('php://input'), true);
$post_data['msg'];
$post_data['stdId'];

0

我有点晚了,但我在这里没有找到我的应用程序中出现的同样问题的答案。我认为这可能会帮助像我这样的人在未来。

如果以上解决方案都不起作用,请确保您的帖子网址末尾没有添加“/”。我因为在帖子请求网址末尾加上“/”而浪费了4个小时。

如果您的URL以“/”结尾,则CI4会对POST请求进行内部重定向。当进行重定向时,POST请求的数据将丢失。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接