Javascript 有没有办法将值(如枚举)从前端(js)连接到后端(php/ruby)?

Javascript 有没有办法将值(如枚举)从前端(js)连接到后端(php/ruby)?,javascript,php,ruby,code-design,Javascript,Php,Ruby,Code Design,如果后端是基于php或ruby的web应用程序,前端是在javascript上编程的,有时我们需要在两侧定义值,以处理通过API与前端后端通信的数据 在javascript中,应该是这样的: var选项={ 选择A:1, 选项B:2, 选择C:3 }; 开关(数据类型) { case options.OPT_A: /* */ 打破 case options.OPT_B: /* */ 打破 case options.OPT_C: /* */ 打破 } 在php中,类似这样的内容: const O

如果后端是基于php或ruby的web应用程序,前端是在javascript上编程的,有时我们需要在两侧定义值,以处理通过API与前端后端通信的数据

在javascript中,应该是这样的:

var选项={
选择A:1,
选项B:2,
选择C:3
};
开关(数据类型)
{
case options.OPT_A:
/* */
打破
case options.OPT_B:
/* */
打破
case options.OPT_C:
/* */
打破
}
在php中,类似这样的内容:

const OPT_A=1;
常数OPT_B=2;
常数OPT_C=3;
但问题是,你必须定义它们两次,每种语言定义一次。这可能会导致错误/不一致

我认为唯一的方法是从服务器定义javascript部分,但我不喜欢用php/ruby代码编写js代码


所以我的问题是。。。有什么好方法可以做到这一点吗?

您可能会想了解Web服务。Web服务本质上是一种功能。您向它传递一些参数,它会返回一些信息。通常用于允许程序访问外部数据。您几乎可以在任何API中看到它们的作用。有关示例,请参见

最简单的例子:

#sinatra routing
get '/webservice/test' do
    content_type :json
    data = {options: {
        opt_a: 1,
        opt_b: 2,
        opt_c: 3
    }}
    JSON.pretty_generate(data)
end
因此,当您访问
您的站点.com/webservice/test
时,您将获得:

{
  "options": {
    "opt_a": 1,
    "opt_b": 2,
    "opt_c": 3
  }
}
在javascript中使用此数据变得微不足道:

var call = new XMLHttpRequest();
call.onreadystatechange = function() {
    if(call.readyState == XMLHttpRequest.DONE) {
        if(call.status == 200) {
            obj = JSON.parse(call.responseText);
            console.log(obj);
        } else if(xmlhttp.status == 400) {
            console.log("error 400");
        } else {
            alert("some other thing happened");
        }
    }
}
call.open("GET", "/webservice/test", true);
call.send(); 
现在,您的数据位于客户端! 具体来说,
obj
将是
Object{options:Object}
,因此您可以使用
obj.options.opt_a
访问3个选项,以获得
1

有一些关于Web服务的简单英语解释

如果您不熟悉http响应代码,可以查看完整的列表。这是javascript代码的
call.status
部分


如果您愿意,可以在jQuery中使用
$.getJSON(“/webservice/test”,function()…)
执行相同的ajax调用。您可以阅读有关它的更多信息

这里有一个解决方案,介绍如何创建PHP枚举并将其作为对象发送到前端

在PHP中,我创建了一个名为Food的枚举类:

abstract class Food
{
    const BANANA = 0;
    const ORANGE = 1;
    const WATERMELON = 2;

    const BANANA_STRING = 'banana';
    const ORANGE_STRING = 'orange';
    const WATERMELON_STRING = 'watermelon';

    const MAP = [
        self::BANANA         => self::BANANA_STRING,
        self::ORANGE         => self::ORANGE_STRING,
        self::WATERMELON     => self::WATERMELON_STRING
    ];

    const REVERSEMAP = [
        self::BANANA_STRING          => self::BANANA,
        self::ORANGE_STRING          => self::ORANGE,
        self::WATERMELON_STRING      => self::WATERMELON
    ];

    static function toString($enum){
        return self::MAP[$enum];
    }
    static function toEnum($string){
        return self::REVERSEMAP[$string];
    }
}
在接下来的步骤中,我将使用Laravel框架,但根据您的项目,它应该基本相同。这里的重要部分是我使用在枚举中创建的::MAP:

use PathToMyLibrary\MyLibrary\Enums\Food;

class FoodController extends Controller {

    public function foodView() {
        $title = "hello";
        $food_enum = Food::MAP;

        // attach these variables to the food view
        return view('food', compact('title', 'food_enum'));
    }

}
现在,在我的food.blade.php文件(Laravel中使用的php html视图模板文件)中,我可以将这个$food_enum php对象转换为JavaScript对象

@section('title')
    {{title}}
@endsection

@section('page_content')
    <div class="page-heading">
        <h1>{{title}}</h1>
    </div>
    <div id="food-app">...your content...</div>
@endsection

@section('includes')
    <script>
        // convert this $food_enum from a PHP object into a JavaScript object
        var food_enum = <?php echo json_encode($food_enum); ?>;
    </script>
@endsection
@节(“标题”)
{{title}}
@端部
@节(“第页内容”)
{{title}}
…您的内容。。。
@端部
@第节(“包括”)
//将此$food_枚举从PHP对象转换为JavaScript对象
var food_enum=;
@端部
此时,JavaScript中会有一个对象与PHP中的相同枚举对象相匹配


不再需要在PHP和JavaScript中维护冗余枚举

如何通过JSON进行通信?在服务器上生成JS是可以接受的,但elclanrs建议使用JSON听起来像是一个可靠的解决方案。@elclanrs您的意思是使用AJAX或在加载页面时从PHP获取数据结构?这是另一种选择,但也不喜欢每次都提出不同的请愿书。一个好方法是,如您所说,以JSON格式生成所有枚举数据,并使其可用于JS。我认为这是我最喜欢的方式。您提到的语言都有一个共同的特点,即它们都理解
JSON
。因此,有了这3条注释,我想最好的方式是让服务器生成一个包含所有“public”(前端可用)数据结构/枚举定义的文件。我想我会考虑使用一个类从多个后端文件生成这个静态文件,因为所有的定义都可以在不同的地方。。