我在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
和CURLOPT_COOKIEJAR
存储Cookie,但我不确定文件的位置。首先,对于每个用户来说,它绝对应该是一个不同的位置,它绝对应该不是一个可公开访问的位置。
我的问题是:如何在Drupal中为每个用户的cURL存储和发送cookie?
答案 0 :(得分:0)
假设您正在使用会话,请使用用户的会话ID来命名cookie文件。 e.g。
curl_setopt(CURLOPT_COOKIEFILE, 'cookies.txt');
会给每个人提供相同的Cookie文件,他们最终会共享相同的Cookie。但是做了
curl_setopt(CURLOPT_COOKIEFILE, 'cookie-' . session_id() . '.txt');
将为每个用户生成一个唯一的会话文件。您将不得不手动删除该文件,否则您将最终得到一个巨大的cookie文件管理器存储库。如果您要更改会话ID(例如session_regenerate_id()
),您将“丢失”Cookie文件,因为会话ID将不再相同。