
在使用 php 与 notion api 交互,特别是进行数据库查询时,一个常见的挑战是确保过滤条件能够正确生效。当开发者尝试根据特定属性值来筛选 notion 数据库中的数据时,如果请求体的结构不符合 notion api 的要求,api 可能不会应用这些过滤条件,而是返回整个数据库的内容。
理解 Notion 数据库查询 API
Notion API 提供了 POST /v1/databases/{database_id}/query 端点,用于查询特定数据库中的页面。这个端点允许通过请求体(Request Body)中的 filter 对象来指定复杂的过滤逻辑,从而只获取符合条件的数据。根据 Notion 官方文档,一个有效的过滤条件通常需要包含在一个名为 filter 的顶级属性中。
例如,一个用于过滤数据库中标题属性的 JSON 结构可能如下所示:
{
"filter": {
"property": "Landmark",
"text": {
"contains": "Bridge"
}
}
}这里,filter 是一个包含具体过滤规则的对象,property 指定了要过滤的属性名称,而其内部的 text 对象则定义了具体的过滤类型(如 contains、equals 等)和值。
常见问题与错误示例
许多开发者在构建 PHP 请求时,可能会直接将过滤条件作为请求体的顶层属性发送,而不是将其嵌套在 filter 键下。例如,以下 PHP 代码片段展示了一个常见的错误构造方式:
立即学习“PHP免费学习笔记(深入)”;
"DataElement", "title"=>["equals"=>"bigHouse"] ]; $data = json_encode($data_array); // ... (cURL 执行和响应处理省略) ?>
当上述 $data_array 被 json_encode 转换为 JSON 字符串后,其结果会是: {"property":"DataElement","title":{"equals":"bigHouse"}}
这个 JSON 结构缺少了 Notion API 所要求的 filter 顶级键。因此,Notion API 会忽略这些看似是过滤条件的参数,并返回数据库中的所有数据,导致查询结果不符合预期。
正确构建过滤条件
解决这个问题的关键在于,将所有过滤逻辑封装在一个名为 filter 的数组(在 JSON 中对应为对象)中。正确的 PHP $data_array 结构应该如下所示:
[
"property"=>"DataElement",
"title"=>["equals"=>"bigHouse"]
]
];
$data = json_encode($data_array);
// ... (cURL 执行和响应处理省略)
?>经过 json_encode 后,这个 $data_array 将生成符合 Notion API 要求的 JSON 字符串: {"filter":{"property":"DataElement","title":{"equals":"bigHouse"}}}
这样,Notion API 就能识别并应用 filter 对象中的过滤条件,从而返回经过筛选的精确结果。
完整的 PHP cURL 示例
下面是一个完整的 PHP 代码示例,展示了如何使用 cURL 发送一个带有正确过滤条件的 Notion 数据库查询请求:
[
"property"=>"DataElement", // 数据库中要过滤的属性名称
"title"=>["equals"=>"bigHouse"] // 过滤条件:标题等于 "bigHouse"
]
];
$data = json_encode($data_array); // 将 PHP 数组编码为 JSON 字符串
// 3. 初始化 cURL
$ch = curl_init();
// 4. 设置 cURL 选项
curl_setopt($ch, CURLOPT_URL, $url); // 请求 URL
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 将响应作为字符串返回,而不是直接输出
curl_setopt($ch, CURLOPT_POST, true); // 设置为 POST 请求
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // POST 请求体数据
// 设置 SSL 验证 (在开发环境中可以禁用,生产环境强烈建议启用)
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
// 设置 HTTP 头信息
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer ' . $token, // 认证令牌
'Notion-Version: ' . $version, // API 版本
'Content-Type: application/json' // 声明请求体是 JSON 格式
));
// 5. 执行 cURL 请求
$resp = curl_exec($ch);
// 6. 检查 cURL 错误
if($e = curl_error($ch))
{
echo "cURL 错误: " . $e;
} else
{
// 7. 解码 API 响应并输出
$decoded = json_decode($resp, true);
echo "API 响应:";
var_dump($decoded);
echo "";
}
// 8. 关闭 cURL 句柄
curl_close($ch);
?>注意事项与最佳实践
-
查阅官方文档: 始终以 Notion 官方 API 文档(https://developers.notion.com/reference/post-database-query)为准,了解每个端点的最新要求和参数结构。API 可能会更新,文档是获取最新信息的最佳来源。
-
JSON 结构精确性: Notion API 对 JSON 请求体的结构要求非常严格。即使是微小的键名错误或层级错误,都可能导致请求失败或过滤条件不生效。使用 json_encode 后的输出进行调试是很有帮助的。
-
错误处理: 在生产环境中,除了 curl_error() 之外,还应该检查 Notion API 返回的响应体中是否包含错误信息(通常在 code 和 message 字段中)。
-
安全管理: 您的 Notion 集成令牌是敏感信息,切勿硬编码在公共代码库中,应通过环境变量或安全的配置管理方式进行存储和访问。
-
API 版本: 务必在 Notion-Version 头中指定一个有效的 API 版本。不指定或指定旧版本可能导致行为不一致或功能缺失。
-
Content-Type 头: 虽然 cURL 在 CURLOPT_POSTFIELDS 是字符串时有时会自动设置 Content-Type: application/x-www-form-urlencoded,但对于 JSON 请求,显式设置 Content-Type: application/json 是一个良好的实践。
总结
通过 PHP 查询 Notion 数据库并应用过滤条件,关键在于正确构造请求体,确保过滤逻辑被封装在 filter 顶级参数中。遵循 Notion API 的规范,仔细核对 JSON 结构,并利用 cURL 的强大功能,可以有效地实现对 Notion 数据库的精准数据检索。在开发过程中,充分利用调试工具检查请求和响应,将大大提高开发效率。











