JSON从AJAX到PHP服务器.记住数据类型


JSON from AJAX to PHP server. Remembering data types

是否可以

使用ajax(使用jQuery)从客户端将JSON数据发送到PHP页面,并将json_decode与所有变量一起使用完全相同的数据类型?我以为 JSON 应该保留它,但如果您将其发送到 PHP,它似乎不起作用。如果它不这样做,那么我不确定为什么我应该使用 JSON。我不妨只使用标准的 POST 请求。

我的问题是我需要将数据发送到 PHP 才能将其插入到 MySQL 中,这需要插入正确的变量类型,但是当数据从 JSON 到达时,它全部转换为字符串。我想我误解了 JSON 应该用于什么。最有可能,如果是这样,任何人都可以向我解释这一点吗?

这是否意味着我需要在整个 Web 应用程序中始终手动转换 PHP 端的所有内容?那将是一个真正的痛苦。

// JavaScript:
$.ajax({
    type: "POST",
    url: "program.php",
    data: {
        posting: true,
        json: JSON.stringify({
            posting: true,
            id: 6,  // should remain an integer
        })
    },
    success: function(data) {
        console.log(data);
    }
});

// PHP:
if (array_key_exists("posting", $_POST)) {
    $result = json_decode($_POST["json"]);
    echo gettype($result->id); // string (all values in $result are strings still)
    exit();
}

编辑:我担心变量类型的原因是因为我正在尝试将预准备语句与MySQL一起使用,并且bind_param函数要求您输入变量类型。这是我为我处理这个问题而创建的 PHP 函数:

public static function insert($query, $params) {        
    $statement = mysqli_prepare(self::$connection, $query);
    foreach ($params as $value) {
        switch (gettype($value)) {
            case "boolean":
                $value = (int) $value;
            case "integer":
                $statement->bind_param("i", $value);
                break;
            case "double":
                $statement->bind_param("d", $value);
                break;
            case "string":
                // it is ALWAYS a string even though some as suppose to be integers
                $statement->bind_param("s", $value);
                break;
            default: 
                echo "error type: " . gettype($value);
                return;
        }
    }
    $statement->execute();
    $statement->fetch();
    $result = $statement->get_result();
    $statement->close();
    return $result;
}

让我们从 JSON 开发人员在他们的规范中没有提到的内容开始:JSON 在字符串上下文中使用时实际上是 JSON。

在这里和我一起逻辑思考。您将如何传输数据类型信息?合理的做法是以某种方式标记它。好吧,JavaScript 这样做的同时,它把你不那么 JSON-还作为一个对象。但是由于$_POST只使用application/x-www-form-urlencodemultipart/form-data,所以你最终会得到字符串或二进制数据。

但是在此状态下,无法在字符串 json 中保存和传输数据类型,直到直接在 JSON 中指定数据类型,如下所示:

{"name": "Food", "value": "Banana", "type": "string"},
{"name": "Drink", "value": "Beer", "type": "string"},
{"name": "Count", "value": "42", "type": "int"}

然后在 PHP 中解析它。或者直接输入bind_param所需的数据类型,并在解码 JSON 后使用它。

哦,是的, stringify以某种方式说明了自己:

JSON.stringify() 方法将 JavaScript 值转换为 JSON 字符串,如果指定了替换器函数,则可以选择替换值,或者如果指定了替换器数组,则可以选择仅包含指定的属性。

延伸阅读:

  • PHP 后变量
  • W3C 表单内容类型
  • jQuery .ajax 函数
  • 本·阿尔曼谈 JSON
  • MDN on JSON.stringify

如果你仍然坚持这个问题,我已经做了一个基本的例子,它涵盖了使用Jquery和PHP页面的HTML/JavaScript(将数据记录到文本文件)

JavaScript 代码 - 索引.html

<a href="#" class="button">Submit</a>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script>
    $(".button").on("click", function(){
        ajaxSubmit();
    });
    var ajaxSubmit = function(){
        var obj = {};
        obj['foo'] = {};
        obj['foo']['type'] = 'integer';
        obj['foo']['value'] = 1;
        obj['bar'] = {};
        obj['bar']['type'] = 'string';
        obj['bar']['value'] = 'hello';
        sendData = JSON.stringify(obj);
        $.ajax({
            type: "POST",
            url: "program.php",
            data: {'json': sendData},
            success: function(data) {
                console.log(data);
            }
        });
    };
</script>

PHP 代码 - 程序.php

<?php
    $data = $_REQUEST;
    $obj = json_decode($data['json']);
    foreach ($obj as $var) {
        switch ($var->type) {
            case 'integer':
                fileWrite('Integer: '.$var->value);
                break;
            case 'string':
                fileWrite('String: '.$var->value);
                break;
        }
    }
    function fileWrite ($string) {
        if (is_array($string)){
            $string = 'Array: '.print_r($string, true);
        }
        if(is_object($string)) {
            $string = 'Object: '.print_r($string, true);
        }
        $fp = fopen('output.txt', 'a');
        fwrite($fp, $string."'n");
        fclose($fp);
    }
?>