我在 Drupal 中有一个 Web 应用程序,它基本上充当其他地方的多页 HTML 表单的代理。我可以使用 cURL 检索页面并使用 DOMDocument 对其进行解析,然后将内容嵌入到<form>
Drupal 表单中:
<?php
function proxy_get_dom($url, $method = 'get', $arguments = array()) {
// Keep a static cURL resource for speed.
static $web = NULL;
if (!is_resource($web)) {
$web = curl_init();
// Don't include any HTTP headers in the output.
curl_setopt($web, CURLOPT_HEADER, FALSE);
// Return the result as a string instead of echoing directly.
curl_setopt($web, CURLOPT_RETURNTRANSFER, TRUE);
}
// Add any GET arguments directly to the URL.
if ($method == 'get' && !empty($arguments)) {
$url .= '?' . http_build_arguments($arguments, 'n', '&');
}
curl_setopt($web, CURLOPT_URL, $url);
// Include POST data.
if ($method == 'post' && !empty($arguments)) {
curl_setopt($web, CURLOPT_POST, TRUE);
curl_setopt($web, CURLOPT_POSTFIELDS, http_build_query($arguments));
}
else {
curl_setopt($web, CURLOPT_POST, FALSE);
}
$use_errors = libxml_use_internal_errors(TRUE);
try {
$dom = new DOMDocument();
$dom->loadHTML(curl_exec($web));
}
catch (Exception $e) {
// Error handling...
return NULL;
}
if (!isset($dom)) {
// Error handling...
return NULL;
}
libxml_use_internal_errors($use_errors);
return $dom;
}
function FORM_ID($form, &$form_state) {
// Set the initial URL if it hasn't already been set.
if (!isset($form_state['remote_url'])) {
$form_state['remote_url'] = 'http://www.example.com/form.faces';
}
// Get the DOMDocument
$dom = proxy_get_dom($form_state['remote_url'], 'post', $_POST);
if (!isset($dom)) {
return $form;
}
// Pull out the <form> and insert it into $form['embedded'].
$nlist = $dom->getElementsByTagName('form');
// assert that $nlist->length == 1
$form['embedded']['#markup'] = '';
foreach ($nlist->item(0)->childNodes as $childnode) {
// It would be better to use $dom->saveHTML but it does not accept the
// $node parameter until php 5.3.6, which we are not guaranteed to be
// using.
$form['embedded']['#markup'] .= $dom->saveXML($childnode);
}
// Apply some of the attributes from the <form> element onto our <form>
// element.
if (isset($element->attributes)) {
foreach ($nlist->item(0)->attributes as $attr) {
if ($attr->nodeName == 'action') {
$form_state['remote_action'] = $attr->nodeValue;
}
elseif ($attr->nodeName == 'class') {
$form['#attributes']['class'] = explode(' ', $attr->nodeValue);
}
elseif ($attr->nodeName != 'method') {
$form['#attributes'][$attr->nodeName] = $attr->nodeValue;
}
}
}
return $form;
}
function FORM_ID_submit($form, &$form_state) {
// Use the remote_action as the remote_url, if set.
if (isset($form_state['remote_action'])) {
$form_state['remote_url'] = $form_state['remote_action'];
}
// Rebuilt the form.
$form_state['rebuild'] = TRUE;
}
?>
但是,嵌入的表单不会超过第一步。问题似乎是代理背后的页面正在设置一个会话 cookie,我在上面的代码中忽略了它。CURLOPT_COOKIEFILE
我可以用and存储 cookie CURLOPT_COOKIEJAR
,但我不确定文件应该在哪里。一方面,对于每个用户来说,它绝对应该是一个不同的位置,而且它绝对不应该是一个可公开访问的位置。
我的问题是:如何在 Drupal 中存储和发送来自 cURL 每个用户的 cookie?