评估存储在数据库中的代码字符串。

huangapple go评论105阅读模式
英文:

Eval piece of code stored in DB as string

问题

我正在将我的应用程序从PHP迁移到Go。我正在将一些代码片段存储在MySQL中以进行评估,例如:checkGeo('{geo:["DE","AU","NL"]}') && check0s('{os:["android"]}')。在PHP中很容易,只需使用eval($stringToEval),但在Go语言中该如何实现呢?

英文:

I'm moving part of my application from PHP to Go. I'm storing some pieces of code to eval in MySQL, for example: checkGeo('{geo:["DE","AU","NL"]}') && check0s('{os:["android"]}'). In PHP it is easy, just eval($stringToEval), but how can this be done in Go lang?

答案1

得分: 3

在像PHP这样的解释型语言中,实现eval相当简单。但是Go是一种编译型语言。要在Go中实现eval,需要编写一个Go的解释器。这并非不可能,但是这是一项庞大的工作。

-编辑
你可以查看https://godoc.org/bitbucket.org/binet/go-eval/pkg/eval,这可能是你想要的。如果它不能满足你的需求,你可以进一步扩展它。但它并不是一个完整的解释器。

英文:

In an interpreted language like PHP, implementing eval is fairly simple. But Go is a compiled language. To implement eval in Go would require writing an interpreter for Go. This would not be impossible, but it would be a big job.

-Edit<br />
You can have a look at https://godoc.org/bitbucket.org/binet/go-eval/pkg/eval which might do what you want. If it doesn't you could then maybe expand on it a bit. It isn't a full interpreter though.

答案2

得分: 1

根据你提供的示例,似乎可以相对容易地编写一些 Go 代码来评估 checkGeo() 或 checkOs() 规则;我认为这可能是最好的方法。

但这不是你所问的...

另一个选择是使用 Lua 编写规则,并使用 https://github.com/aarzilli/golua 运行它们,或者使用 JavaScript 并使用 https://github.com/robertkrimen/otto

英文:

Based on the examples you gave it seems like it'd be trivial-ish to build a bit of go code that knows how to evaluate checkGeo() or checkOs() rules; I think that'd be the best approach.

But that's not what you asked...

Another option would be to write the rules in Lua and run them with https://github.com/aarzilli/golua or in Javascript and use https://github.com/robertkrimen/otto

答案3

得分: 1

你不需要引入一个完整的解释器来处理这种情况:编写一个简单的解析器,将你的脚本分解成语法树,然后编写代码来遍历该树并“评估”它。对于像你的简单情况来说,这并不是那么难。当然,你的语法可能比PHP的简单得多,因为你不需要PHP解释器的全部功能。

一个简单的例子是rpn,但你也可以更简单地发明一种存储查询的方式,比如JSON。

另外请注意,Go语言有一个Go解析器,以Go包的形式存在——go/parser,因此你可以使用(最小化的)Go语法编写查询,用go/parser解析它们,然后只实现一个评估器,该评估器将遍历解析器生成的AST并计算结果。但是,考虑到你提供的示例,我认为这可能是过度工程化了。

还有一个小问题:将要由完整解释器(如PHP)评估的代码存储起来是危险的:如果有人以某种方式在你的表中注入了对exec()或类似函数的调用,结果将是不理想的。因此,从安全的角度来看,拥有一个简单的解析器/评估器也是一个优势。

英文:

You don't need to pull in a full-blown interpreter for this sort of thing: write a simple parser that would pull your script apart into the syntax tree, and then write code that would walk that tree and "evaluate" it. It's not really that hard for simplistic cases like yours. And of course, your syntax might be made way simpler than PHP's since you don't want the full power of PHP's evaluator.

One simple example is rpn, but you can go simpler and invent a way to store your queries in, say, JSON.

Also note that Go has a Go parser in the form of a Go package &mdash; go/parser so you can write your queries using (minimal) Go syntax, parse them with go/parser and only implement an evaluator which would walk the AST produced by the parser and calculate the result. But I think this would be an overengeneering, given the example you've provided.

And a minor nitpick: storing the code which is to be evaluated by a full-blown evaluator, like PHP, is dangerous: if someone somehow manages to inject a call to exec() or something like this in your table, the result will be suboptimal. So having a primitive parser/evaluator is an upside from the security standpoint as well.

huangapple
  • 本文由 发表于 2014年3月23日 20:55:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/22591198.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定