2013-10-22 44 views
0

我在Drupal中有一個Web應用程序,它基本上是作爲其他地方的多頁HTML表單的代理。我能夠檢索與捲曲的頁面,並與DOM文檔解析它,然後嵌入<form>內容的Drupal的表單中:cURL和Drupal:存儲每個用戶的遠程Cookie

<?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_COOKIEFILECURLOPT_COOKIEJAR存儲Cookie,但我不確定該文件應該位於何處。一方面,它肯定應該是每個用戶的不同位置,並且它肯定應該是而不是是一個公共訪問位置。

我的問題是:如何在cURL中按用戶在Drupal存儲和發送cookie?

回答

0

假設您使用會話,然後使用用戶的會話ID來命名cookie文件。例如

curl_setopt(CURLOPT_COOKIEFILE, 'cookies.txt'); 

會給每個人相同的cookie文件,他們最終會共享相同的cookie。但是做

curl_setopt(CURLOPT_COOKIEFILE, 'cookie-' . session_id() . '.txt'); 

會爲每個用戶產生一個唯一的會話文件。您將不得不手動刪除該文件,否則您將最終得到一個巨大的cookie文件存儲庫。如果您要更改會話ID(例如session_regenerate_id(),則會「丟失」Cookie文件,因爲會話ID將不再一樣。

+0

我正在尋找一個答案,告訴我在哪裏放置'Cookies.txt'文件,這樣它將是安全的,或者如何避免完全使用文件。例如,通過使用PHP流包裝器(如果這可能與cURL函數)。也可以在Drupal中使用' $ user-> uid'而不是'session_id()',然後我不必刪除任何文件。 – meustrus

+0

curl需要cookies的文件,不能真的解決這個問題。你不能傳入一個流包裝器或其他「映射到X」類型 - 它只需要一個文件名。至於放置文件的位置 - 文檔根目錄之外的任何地方都可以。「 –

+0

」文檔根目錄之外的任何地方「在PHP中不可移植。控制我的環境但我不想處理在我可以進入版本控制的範圍之外設置該環境。 – meustrus