Php 如何在Marklogic中的光学API查询中使用用户在web应用程序中设置的参数值?
大宗报价 我有一个web应用程序(用js编写),用户可以在其中输入一个名称(以及其他条件),然后对ML数据库执行搜索,并返回与该名称(或其他搜索条件)关联的一些数据的表格表示。在开发的第一个阶段,我编写了opticapi查询,查询的where语句中硬编码了name的值。我这样做是为了测试RESTAPI是否正确地调用了查询,等等。一切都正常,我可以看到web应用程序中返回的硬编码名称的正确结果。现在,我想将用户提供的name值传递给opticapi查询(EntityInformation\u opticapi\u query.json),以替换where语句中的硬编码值。我该怎么做?提前谢谢Php 如何在Marklogic中的光学API查询中使用用户在web应用程序中设置的参数值?,php,marklogic,marklogic-9,marklogic-dhf,Php,Marklogic,Marklogic 9,Marklogic Dhf,大宗报价 我有一个web应用程序(用js编写),用户可以在其中输入一个名称(以及其他条件),然后对ML数据库执行搜索,并返回与该名称(或其他搜索条件)关联的一些数据的表格表示。在开发的第一个阶段,我编写了opticapi查询,查询的where语句中硬编码了name的值。我这样做是为了测试RESTAPI是否正确地调用了查询,等等。一切都正常,我可以看到web应用程序中返回的硬编码名称的正确结果。现在,我想将用户提供的name值传递给opticapi查询(EntityInformation\u op
所有者编辑 应用程序是用PHP编写的,我复制了下面的代码。在这里,您可以看到调用opticapi查询的位置以及构建参数的位置
<?php
if (!defined('RSS_BASE_URL')) exit;
use MarkLogic\MLPHP as MLPHP;
function rss_api_call($json, $params = array(), $resource = 'rows', $verb = 'POST')
{
$json = __DIR__ . '/json/' . $json;
if (!file_exists($json)) return false;
$request = new MLPHP\RESTRequest('POST', 'rows', $params, file_get_contents($json), array('Content-type' => 'application/json'));
$response = rss_get_client()->send($request);
return json_decode($response->getBody());
}
function rss_api_entities()
{
$params = array();
return rss_api_call('EntityInformation_Optic_API_Query.json', $params);
//return (empty($params)) ? '' : rss_api_call('EntityInformation_Optic_API_Query.json', $params);
}
function rss_api_search()
{
$params = array();
if (isset($_POST['companyname']) && !empty($_POST['companyname']))
{
$params['CompanyName'] = htmlspecialchars($_POST['companyname']);
}
if (isset($_POST['EIN']) && !empty($_POST['ein']))
{
$params['EIN'] = htmlspecialchars($_POST['ein']);
}
if (isset($_POST['city']) && !empty($_POST['city']))
{
$params['EntityCity'] = htmlspecialchars($_POST['city']);
}
if (isset($_POST['state']) && !empty($_POST['state']))
{
$params['EntityState'] = htmlspecialchars($_POST['state']);
}
if (isset($_POST['zip']) && !empty($_POST['zip']))
{
$params['EntityZip'] = htmlspecialchars($_POST['zip']);
}
return rss_api_call('SearchResults_Optic_API_Query.json', $params);
//return (empty($params)) ? '' : rss_api_call('SearchResults_Optic_API_Query.json', $params);
}
function rss_asset_path($path, $file_name)
{
global $rss_manifest;
if (empty($rss_manifest))
{
ob_start();
include(__DIR__ . '/../manifest.json');
$rss_manifest = json_decode(ob_get_clean(), true);
}
if (isset($rss_manifest[$file_name]))
{
$file_name = $rss_manifest[$file_name];
}
return RSS_ASSET_PATH . $path . '/' . $file_name;
}
function rss_box($title, $content)
{
echo '<div class="rss-box">' .
'<div class="rss-box-title">' . $title . '</div>' .
'<div class="rss-box-content">' . $content . '</div>' .
'</div>';
}
function rss_get_client()
{
$mlphp = new MLPHP\MLPHP(array
(
'host' => RSS_API_HOST,
'port' => RSS_API_PORT,
'version' => RSS_API_VERSION,
'username' => RSS_API_USERNAME,
'password' => RSS_API_PASSWORD
));
return $mlphp->getClient();
}
function rss_hidden_search_fields()
{
echo '<div class="rss-hidden">';
$fields = array('debug', 'companyname', 'ein', 'city', 'state', 'zip');
foreach ($fields as $field)
{
echo (isset($_POST[$field])) ? '<input name="' . $field . '" type="hidden" value="' . htmlspecialchars($_POST[$field]) . '" />' : '';
}
if (!empty($_POST['social']))
{
$social = (is_array($_POST['social'])) ? $_POST['social'] : array($_POST['social']);
foreach ($social as $social_network)
{
echo '<input name="social[]" type="hidden" value="' . htmlspecialchars($social_network) . '" />';
}
}
echo (empty($_POST['social-select-all'])) ? '' : '<input name="social-select-all" type="hidden" value="1" />';
echo '</div>';
}
Part of the EntityInformation_Optic_API_Query.json is below
-----
edit (information from a comment below):
The request will be a POST to /v1/rows. Does the following payload look correct?
```javascript
{
"$optic": {
"ns": "op",
"fn": "operators",
"args": [
{
"ns": "op",
"fn": "from-view",
"args": [ "TestSchema", "SUT", null, null ]
},
{
"ns": "op",
"fn": "where",
"args": [
{
"ns": "op",
"fn": "eq",
"args": [
{
"ns": "op",
"fn": "col",
"args": [ "CompanyName" ]
},
"${req.params.CompanyName}"
]
}
]
}
这取决于您如何设置应用程序
RESTAPI
如果您的代码是RESTAPI扩展,那么您编写的函数将有一个params
参数。对于JavaScript,这将是一个对象。看见从文档的该部分:
如果请求被放入/v1/resource/my ext?rs:p=1&rs:p=2
,则参数p
的值为[“1”,“2”]
主模块
如果客户端将通过常规(非REST)主模块访问代码,则使用
编辑:我用你评论中的更多信息更新了你的问题。在我看来,您已经有了一个中间层,它从客户端(浏览器)获取参数,并使用这些参数构建一个要传递到/v1/rows
的查询。它看起来像是要插入“${req.params.CompanyName}”
,以便中间层获得req.params.CompanyName
的值,然后将其放入发送到MarkLogic的字符串中
“${req.params.CompanyName}”
是否可能被添加到一个引号完整的字符串中,这样中间层就不能进行插值?如果您可以提供有关如何构建/v1/rows
有效负载的更多信息,我们可能会提供更多帮助 对于Java或Node.js web应用程序,最好的方法可能是编写一个函数,该函数接受值并生成并返回查询
在其他环境中,使用JSON表示并插入值是最安全的
通过转义,可以将光学查询的JSON序列化组装为字符串,尽管有时很难调试。在MarkLogic enode上,JSON被解析为JSON而不是经过计算,因此不存在注入攻击的风险,但解析失败是可能的
希望这能有所帮助,我认为您需要使用“绑定”参数。所以你的计划是这样的:
{
"$optic": {
"ns": "op",
"fn": "operators",
"args": [
{
"ns": "op",
"fn": "from-view",
"args": [
"TestSchema",
"SUT",
null,
null
]
},
{
"ns": "op",
"fn": "where",
"args": [
{
"ns": "op",
"fn": "eq",
"args": [
{
"ns": "op",
"fn": "col",
"args": [
"CompanyName"
]
},
{
"ns": "op",
"fn": "param",
"args": [
"companyName"
]
}
]
}
]
}
]
}
}
然后,当您将其发布到/v1/行时,需要设置companyName
bind参数和类型。因此,在您的帖子中添加以下参数:
bind:companyName=${req.params.CompanyName}
bind:companyName:type=xs:string
假设${req.params.CompanyName}
包含用户传递的公司名称值
另一方面,手工处理序列化的光学计划可能会很困难。我建议您将其放在REST扩展之后,只需传入参数。如果您确实希望将光学计划保留在中间层中,则始终可以使用MarkLogic的查询控制台,在需要参数化值的地方,使用适当的op.param()
调用生成计划。例如:
const op=require('/MarkLogic/optic');
常量计划=op
.fromView(“TestSchema”、“SUT”)
.在哪里(
op.eq(
op.col(“公司名称”),op.param(“公司名称”)
)
)
plan.export()
请发布当前代码的示例。与其将CompanyName与查询一起发送,并期望它在服务器端插入,不如在客户端插入,例如在从PHP发送之前?它确实使用REST API。这看起来完全正确吗?{“$optic”:{“ns”:“op”,“fn”:“operators”,“args”:[{“ns”:“op”,“fn”:“from view”,“args”:[“TestSchema”,“SUT”,“null,null]},{“ns”:“op”,“fn”:“where”,“args”:[{“ns”:“op”,“fn”:“eq”,“args”:[{“ns”:“op”,“fn”:“col”,“args”:[“CompanyName”},${req.params.CompanyName}],你好,Dave,谢谢你的指导。我对所有这些都不熟悉,因为我确信这是显而易见的。我已经更新了我的原始问题,并添加了一些调用optic api查询的PHP代码。你好,James。我想更好地理解你的评论“手工处理序列化的optic计划”和“这是在一个REST扩展后面".所以,为了清楚起见,我通过QConsole用javascript编写了Optic API查询,然后将其序列化为JSON。然后我认为在PHP中发生的是一个REST API调用了该序列化查询。这是应该发生的,但在我们的情况下可能不会发生的吗?绑定工作了!现在我只需要更好地理解我所做的正在进行。感谢您的帮助,非常感谢!我很高兴为您@Meghanoonan工作。关于您的后续问题,您使用的序列化计划是正确的,只要您坚持在QConsole中生成它们并使用绑定参数作为变量,您就应该是好的。“手动”评论是指您正在编辑计划并将“${req.params.CompanyName}”直接添加到计划中,即手动编辑序列化计划。