2013-03-05 67 views
0

我正在嘗試爲Strava.cz製作第三方午餐訂單系統。我已經建立了一個應該做的圖書館。除了strava_czCose函數,一切都可以工作。它不會拋出錯誤,但什麼也不做。他們的服務器基於Windows ASPX,因此很難理解所有傳輸的數據。這是整個代碼:PHP第三方午餐訂購

<?php 
/** 
* Additional function for DOMDocument 
* * * * * 
* @param DOMDocument $DOMDocument Document where you want to search 
* @patam string $className Name of the class you are searching of 
* * * * * 
*/ 
function getElementsByClassName(\DOMDocument $DOMDocument, $className) { 
$Elements = $DOMDocument->getElementsByTagName("*"); 
$Matched = array(); 

for($i=0;$i<$Elements->length;$i++) { 
    if(in_array($ClassName, explode(' ', $Elements->item($i)->attributes->getNamedItem('class')->nodeValue))) { 
    $Matched[]=$Elements->item($i); 
    } 
} 

return $Matched; 
} 

$strava_czHeader="User-Agent:(none; StravaCekujNET; Linux x86_64; rv:1.0)\r\nAccept:(text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8)\r\nAccept-Language:(cs,sk;q=0.8,en;q=0.6,en-gb;q=0.4,en-us;q=0.2)\r\nAccept-Encoding:(gzip, deflate)\r\nDNT:(1)\r\nConnection:(keep-alive)\r\n"; 
$strava_czHandle="n/a"; 

/** 
* * * * * * * * * * * * * * * * 
* Přihlášení (strava_czLogin) * 
* * * * * * * * * * * * * * * * 
* @param int|string $machine Zařízení (4 číslice, string v případě, že začíná nulou) 
* @param int|string $user Uživatel (10 číslic, string v případě, že začíná nulou) 
* @param string $pass Heslo pro přihlášení 
* * * * * 
*/ 
function strava_czLogin($machine,$user,$pass){ 
global $strava_czHeader; 
global $strava_czHandle; 

//Zašle první požadavek > $dom 
$src = file_get_contents('http://m.strava.cz/Stravnik/formprihlaseni.aspx',false,stream_context_create(array('http'=>array('header' => $strava_czHeader)))); 
$dom = new domDocument;  //Vytvoří DOM 
$doc->strictErrorChecking = false; 
    $src = mb_convert_encoding($src, 'HTML-ENTITIES', "UTF-8"); 
$dom->loadHTML($src);   //Načte HTML 
unset($http_response_header, $src); //Uvolní paměť 

//Zpracuje přijatá data a zjistí klíč > $key 
$query['viewstate'] = $dom->getElementById('__VIEWSTATE')->getAttribute('value'); 
$query['eventvalidation'] = $dom->getElementById('__EVENTVALIDATION')->getAttribute('value'); 
$key = '?__EVENTTARGET'. 
    '&__EVENTARGUMENT'. 
    '&__VIEWSTATE='.urlencode($query['viewstate']). 
    '&__EVENTVALIDATION='.urlencode($query['eventvalidation']). 
    '&ctl00%24ContentPlaceHolder1%24txtZarizeni='.urlencode($machine). 
    '&ctl00%24ContentPlaceHolder1%24txtUzivatel='.urlencode($user). 
    '&ctl00%24ContentPlaceHolder1%24txtHeslo='.urlencode($pass). 
    '&ctl00%24ContentPlaceHolder1%24butOdeslat=Odeslat'; 
unset($dom, $query); //Uvolní paměť 

//Zašle požadavek > $src, $http_response_header 
$src = file_get_contents('http://m.strava.cz/Stravnik/formprihlaseni.aspx'.$key,false,stream_context_create(array('http'=>array('header' => $strava_czHeader)))); 
unset($key, $src); //Uvolní paměť 


//Zpracuje přijaté sušenky (mňam!) 
$i = 1; 
$strava_czHandle = array(); 
$strava_czHandle['cookies'] = ""; 
foreach ($http_response_header as $value) { 
    $preg = preg_match('/^Set-Cookie:\s*.[^=]*=.[^;]*/m', $value, $matches); 
    if ($preg) { 
    foreach ($matches as $match) { 
    $strava_czHandle['cookies'] .= substr($match, 12); //Zápis do handleru 
    //Substring proto, aby se do handleru nezapisovalo i "SetCookie: " 
    } 
    } 
} 
unset($i, $http_response_header, $matches, $match, $value); //Uvolní paměť 

//Případně vyhodí chybu 
if ($strava_czHandle['cookies']==""){throw new Exception("noResult");} 
} 


/** 
* * * * * * * * * * * * * * * * 
* Odhlášení (strava_czLogout) * 
* * * * * * * * * * * * * * * * 
*/ 
function strava_czLogout(){ 
global $strava_czHandle; 

if ($strava_czHandle=="n/a") {throw new Exception("notLogged");} 

//Zašle požadavek 
$src = file_get_contents('http://m.strava.cz/Stravnik/odhlaseni.aspx',false,stream_context_create(array('http'=>array('header' => $strava_czHeader."Cookie: ".$strava_czHandle['cookies']."\r\n")))); 

//Zkontroluje správnost přijatých dat 
if (preg_match('/<form.*[^>]action="Default.aspx".*[^>]>/m',$src)){ 
    $strava_czHandle="n/a"; 
} else { 
    throw new Exception("unknownError"); 
} 
} 


/** 
* * * * * * * * * * * * * * * * * * * * * 
* Získání jídelníčku (strava_czGetList) * 
* * * * * * * * * * * * * * * * * * * * * 
*/ 
function strava_czGetList(){ 
global $strava_czHeader; 
global $strava_czHandle; 

if (!$strava_czHandle||$strava_czHandle=="n/a") {throw new Exception("notLogged");} 

//Zašle požadavek > $dom 
$src = file_get_contents('http://m.strava.cz/Stravnik/objednavky.aspx',false,stream_context_create(array('http'=>array('header' => $strava_czMozHeader."Cookie:".$strava_czHandle['cookies']."\r\n")))); 
$dom = new domDocument;    //Vytvoří DOM 
$doc -> strictErrorChecking = FALSE; 
    $src = mb_convert_encoding($src, 'HTML-ENTITIES', "UTF-8"); 
$dom -> loadHTML($src);    //Načte HTML 
unset($http_response_header, $src); //Uvolní paměť 

//Zpracuje přijatá data > $nodeArray, $xpath 
$tbl = $dom -> getElementById('tblObjednavky') -> childNodes; 
$nodeArray=array(); $j=-1; $class = null; 
foreach ($tbl as $item) { 
    if (($item -> getAttribute('class')) === 'tblObjednavkyDatum') {$j++;} 
    $nodeArray[$j][] = $item; 
} 
$xpath = new DOMXPath($dom); 
unset($dom, $tbl, $j, $class, $item); 

/* 
    Vytvořeno dvourozměrné pole. První rozměr určuje den a druhý konkrétní node 
    (0 pro řádek s datem, vyšší číslo pro řádek s jídlem). 
*/ 

//Roztřídí přijatá data > $result 
$result = array(); 
$i = 0; 
foreach ($nodeArray as $item) { 
    $result[$i]['chosen'] = null; 
    $result[$i]['choosable'] = false; 
    $result[$i]['day'] = null; 
    $j = -1; 
    foreach ($item as $subitem) { 
    if ($j > -1) { 
    //Nastaví hodnoty, které jsou pro každou volbu individuální 
    $result[$i]['name'][$j] = substr($xpath -> evaluate('./td[4]', $subitem) -> item(0) -> textContent, 4); 

    /* 
     Lowercase 
     Všechny bílé znaky převést na mezeru a zakázat více mezer za sebou (chování jako HTML bez white-space:pre) 
     Za každou tečku a čárku, za kterou není mezera, přidat mezeru. 
    */ 
    $result[$i]['name'][$j] = preg_replace('([\.,])', '$0 ', $result[$i]['name'][$j]); 
    $result[$i]['name'][$j] = preg_replace('/\s+/m',' ', mb_strtolower($result[$i]['name'][$j], 'utf-8')); 

    if ($xpath -> evaluate('./td[2]/img', $subitem) -> length) {$result[$i]['chosen'] = $j;} 
    $x = $xpath -> evaluate('./td[3]/span/input', $subitem); 
    if ($x -> length) { 
    $result[$i]['choosable'] = true; 
    $result[$i]['day'] = $x -> item(0) -> getAttribute('name'); 
    $result[$i]['lunch'][$j] = $x -> item(0) -> getAttribute('value'); 
    } 
    } 
    $j++; 
    } 
    //Nastaví hodnoty, které platí pro celý den 
    $result[$i]['date'] = $item[0] -> textContent; 
    /* TODO Převést datum na DD/MM/YYYY */ 
    $i++; 
} 

//Vrátí výsledné hodnoty 
if ($result == array()) {throw new Exception("noResult");} else {return $result;} 
} 

/** 
* * * * * * * * * * * * * * * * * * * * 
* Objednávání jídel (strava_czChoose) * 
* * * * * * * * * * * * * * * * * * * * 
*/ 
function strava_czChoose($list) { 
global $strava_czHeader; 
global $strava_czHandle; 

if (!$strava_czHandle||$strava_czHandle=="n/a") {throw new Exception("notLogged");} 

//Pošle první požadavek (získá ty mrkvosofťácký "chujoviny", jak by řekl Keby) > $dom, $list 
$src = file_get_contents('http://m.strava.cz/Stravnik/objednavky.aspx',false,stream_context_create(array('http'=>array('header' => $strava_czMozHeader."Cookie:".$strava_czHandle['cookies']."\r\n")))); 
$dom = new domDocument; //Vytvoří DOM 
$doc->strictErrorChecking = false; 
    $src = mb_convert_encoding($src, 'HTML-ENTITIES', "UTF-8"); 
$dom->loadHTML($src); //Načte HTML 
unset($http_response_header,$src); 

//Zpracuje data a zjistí klíč > $key, $list 
$query['viewstate'] = $dom->getElementById('__VIEWSTATE')->getAttribute('value'); 
$query['eventvalidation'] = $dom->getElementById('__EVENTVALIDATION')->getAttribute('value'); 
$key = '?_EVENTTARGET=butOdeslat'. 
     '&_EVENTARGUMENT'. 
     '&_VIEWSTATE='.urlencode($query['viewstate']). 
     '&_EVENTVALIDATION='.urlencode($query['eventvalidation']); 
unset($dom,$query); 

//Ze zadání vytvoří string dotazu > $data, $key 
$data = ''; 
foreach ($list as $day => $lunch) { 
    $data .= '&'.urlencode($day).'=radObjednavka'.urlencode($lunch); 
} 
var_dump('http://m.strava.cz/Stravnik/objednavky.aspx'.$key.$data); 

//Pošle druhý požadavek (odešle objednávku), případně vyhodí error 
file_get_contents('http://m.strava.cz/Stravnik/objednavky.aspx'.$key.$data,false,stream_context_create(array('http'=>array('header' => $strava_czMozHeader."Cookie:".$strava_czHandle['cookies']."\r\n")))); 
if (preg_match('/500/',$http_response_header)) {throw new Exception("unknownError");} 
} 

try {strava_czLogin(/*secret*/);} 
catch (Exception $e) {exit("</div><div>Přihlášení se nezdařilo, chyba: ".($e -> getMessage()));} 
try {$r=strava_czGetList();} 
catch (Exception $e) {exit("</div><div>Zjištení jídel se nezdařilo, chyba: ".($e -> getMessage()));} 
try {strava_czChoose(array('2013-03-121' => 'P754'));} 
catch (Exception $e) {exit("</div><div>Chyba při odesílání objednávek: ".($e -> getMessage()));} 
try {strava_czLogout();} 
catch (Exception $e) {exit("</div><div>Odhlaseni se nezdařilo, chyba: ".($e -> getMessage()));} 
var_dump($r); 
?> 

我不知道什麼是錯的。對不起,評論,他們在捷克,你可以使用谷歌翻譯,但它的翻譯不是doubleplusgood。 感謝您的幫助,m93a

編輯:我發現如果服務器返回HTTP 302,這是一個可以接受的選擇。我得到HTTP 200.我甚至嘗試使用POST而不是GET,但仍然得到200.

+0

您是否知道您剛剛在線發佈工作用戶/登錄對? – 2013-03-05 16:02:53

+0

是:) 這是一個測試,沒有任何東西可以被破壞。 (或者我希望如此) – m93a 2013-03-05 18:07:08

+0

這個問題得到解答,登錄數據被刪除。感謝你的付出。 – m93a 2013-03-09 22:16:53

回答

0

最後,我找到了原因。我徹底比較了瀏覽器的HTTP請求和我的應用程序的請求,發現__EVENTTARGET應該設置爲'butOdeslat2'。還有一些小錯誤,但我很快找到並修復它們。

現在一切正常。