Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php/COM] Component Object Model + API
Forum PHP.pl > Forum > PHP
woolkan
Witam,

mam bardzo nietypowy problem. Potrzebuje napisać aplikacje w php która będzie wykożystywać API zainstalowane na systemie windosowym. Do API mam dostęp przez COM (Component Object Model). Wiem że w php COM jest dostępny tylko dla wersji Windosowych więc postawiłem sobie pod XP serwer IIS oraz PHPv5.1.6.

Problem jest tego typu: jak dostać się do dostarczonego API? w necie nic nie znalazłem co mogłoby mnie naprowadzić jak używać COM w php i prawdę mówiąc nie mam zielonego pojęcia jak uruchomić to API z php sad.gif w manualu php też niewiele pisze:(

Plik PDF z dokumentacją znajduje się pod tym adresem: plik pdf.

API dotyczy platformy inwestycyjnej o której możesz poczytać na tej stronie: http://cms-forex.com/, dodatkowo możesz załozyć konto demo które będzie potrzebne do testowania API. Sama platforma oraz API dla tej platformy jest dostępne na stronie http://vtsystems.com/en/products/.

I teraz smile.gif po zainstalowaniu platformy (VT Trader) na dysku a następnie API (VT Trader API) możesz mieć dostęp do swojego konta inwestycyjnego poprzez inne oprogramowania niżeli VT Trader (to chyba oczywiste). W katalogu gdzie instaluje się API są dostępne przykłady dla różnych języków programowania takich jak VB, C#, PERL, JAVA oraz pliki excelowskie z makrami pisanymi w VB dla excela. Brak przykładu dla php smile.gif ;P
Moim zadaniem jest napisanie aplikacji która będzie umożliwiała połączenie się z serwerami platformy (dla demo serwera adres: vtdemo.fxserver.com) a następnie pobranie informacji o stanie konta (czyli otwarte pozycje stan konta etc.) oraz sprawdzenie aktualnych notowań. W sumie całość będzie podobna do przykładowego pliku excelowego z katalogu z API. Cała aplikacja ma chodzić na serwerze z systemem Windows XP (najpierw a później będzie migracja na win2k3) a dostęp musi być poprzez WWW.

Defakto całość nie wydaje się jakoś szczególnie trudna zwarzywszy że API dostarcza gotowych funkcji które mają zwracać z serwera odpowiednie dane więc moja praca będzie się ograniczać do obrobienia i wyświetlenia danych wyjściowych i tyle.
Najtrudniejszą rzeczą w chwili obecnej jest połączenie się poprzez API. Nigdy wcześniej nie miałem do czynienia z COM i dlatego to dla mnie jest nie do przejścia w chwili obecnej sad.gif
Co prawda mógłbym napisać w jakimś języku programowania lecz niestety c++ znam słabo a za jave dopiero się zabrałem więc inne języki poza php odpadają.


Z góry wielkie dzięki wszystkim za ewentualną pomoc,
woolkan smile.gif
Seth
Zacznij od tego:

  1. <?php
  2. $vtApi = new COM("vtapi.vt_api");
  3. $result = $vtApi->login('UserName', 'Password', 'ServerID');
  4. ...
  5. ?>



Nie instalowalem tego API ale w ten sposob powinienes uruchomic tego COMa.
Potestuj wywolania roznych funkcji i objektow jakie zwracaja.

Jakby co pisz na forum winksmiley.jpg

P.S.
Sprawdz jeszcze jakis gotowy przyklad czy biblioteka dziala jak nalezy.
woolkan
Cytat(Seth @ 6.10.2006, 00:41:51 ) *
Zacznij od tego:

  1. <?php
  2. $vtApi = new COM("vtapi.vt_api");
  3. $result = $vtApi->login('UserName', 'Password', 'ServerID');
  4. ...
  5. ?>

Nie instalowalem tego API ale w ten sposob powinienes uruchomic tego COMa.
Potestuj wywolania roznych funkcji i objektow jakie zwracaja.

Jakby co pisz na forum winksmiley.jpg

P.S.
Sprawdz jeszcze jakis gotowy przyklad czy biblioteka dziala jak nalezy.


Z gotowych przykładów sprawdzałem plik excelowski i tam wszystko chodzi jak burza smile.gif bez jakichkolwiek problemów.

a co do php to chyba jest gdzieś problem tylko jeszcze nie wiem gdzie. Jeśli uruchomiłem kod:
  1. <?php
  2. $obiekt = new COM("vtapi.vt_api");
  3. print_r($obiekt->GetServerList());
  4. ?>
to ładnie się wyświetla (IE - na stronie widać, FireFox - w źródło trzeba zaglądnąć by zobaczyć) spis serwerów tak jak to jest zamieszczone w manualu do API.
Natomiast jeśli próbuję się zalogować na serwerze poprzez API to jużjest problem. Strona się ładuje i ładuje i załadować nie może... sad.gif nie wiem czemu.
kod który użyłem do logowania:
  1. <?php
  2. $obiekt = new COM("vtapi.vt_api");
  3.  
  4. # logowanie
  5. $login = 'kurapazura';
  6. $pass = 'g68tc0lf';
  7. $acc = $obiekt->login($login, $pass, 0);
  8. print_r($acc);
  9. ?>

W odpowiedzi powinienem dostać wartość INTIGER która określa komunikat z informacją zwrotną z serwera. Login i hasło które tutaj podałem to jest login i hasło do konta demo więc możesz śmiało z nich skorzystać smile.gif (najwyżej założe sobie nowe konto demo do testów smile.gif)

Nie wiem gdzie leży problem. Czy to wina API (chodź na przykładach dostarczonych z API wszystko działa OKI), czy to wina IIS czy teżjest jeszcze coś o czym nie wiem a powinno być uwzględnione sad.gif Cały skrypt jest sprawdzany na WinXPProf z php5.1.6 zainstalowanym serwerem IIS5.1

Czy mógłbyś zainstalować sobie to API i sprawdzić jak działa to u Ciebie? API zajmuje na HDD 2MB więc nie tak dużo smile.gif


Dziękuję za pomoc i pozdrawiam,
woolkan
Seth
OK. Postaram sie pobawic tym troche.
Chociaz odrazu uprzedzam, ze najwczesniej bede mogl do tego zajrzec w poniedzialek :/

Inna sprawa to taka, ze moze sprawdz (zanim ja to zrobie) jak sie zachowuje ten skrypt na Windowsowym Apacheu - bo i on sie do tego nadaje.

Nie wiem czy przypadkiem IIS nie blokuje COMa do wyjscia na zewnatrz.
Z tego co opisales wyglada jakby nie mogl nawiazac polaczenia, a sam COM zaladowal sie bez problemu.
woolkan
Cytat(Seth @ 7.10.2006, 03:09:01 ) *
OK. Postaram sie pobawic tym troche.
Chociaz odrazu uprzedzam, ze najwczesniej bede mogl do tego zajrzec w poniedzialek :/

Inna sprawa to taka, ze moze sprawdz (zanim ja to zrobie) jak sie zachowuje ten skrypt na Windowsowym Apacheu - bo i on sie do tego nadaje.

Nie wiem czy przypadkiem IIS nie blokuje COMa do wyjscia na zewnatrz.
Z tego co opisales wyglada jakby nie mogl nawiazac polaczenia, a sam COM zaladowal sie bez problemu.


Sprawdziłem na Apache'u (koniecznie z załadowanym mod_ssl) smile.gif i odkryłem że IIS nie wypuszcza połączeń SSL a API łączy się poprzez SSL. Efekt jest taki że wszystko co trzeba jest pobierane poprzez API z serwera. Natomiast jest jeden kolejny problem na który się natknąłem sad.gif

Jeśli php łączy się poprzez COM z API to otwierany jest swego rodzaju stały proces który działa dotąd aż go nie zamknie się. Czyli jeśli odpalam pierwszy raz skrypt wywołujący plecenie:
  1. <?php
  2. $vtApi = new COM("vtapi.vt_api");
  3. ?>

to wszystko jest ok. Ale jeśli wywołam ponownie mój skrypt to następuje kolejne wywołanie COM przez co Apache świruje i nie przetwarza skryptu. Jedyny ratunek to restart Apacha.

Najlepszym rozwiązaniem jest sprawdzenie czy COM już został wywołany. I właśnie.. co polecicie? myślałem o funkcji com_get_active_object() sad.gif Albo ja nie rozumiem tej funkcji albo ona nie chce mi działać tak jak należy. Zastanawiałem się też nad przechowywaniem stanu w cookies lub w MySQL ale jeśli zastosuje takie rozwiązanie to nie będę miał tworzonego uchwytu do API więc to nie tędy droga.

Seth (lub ktokolwiek inny smile.gif ) czy mógłbyś mi powiedzieć co mam wpisać jako daną wejściową w funkcji com_get_active_object(string progid). Próbowałem wprowadzić $progid = "vtapi.vt_api" i $progid = "{B4306CAA-55F9-4A84-B792-AA65EA7CECB2}" ale niestety ani dla jednej ani dla drugiej wartości nie działa ta funkcja jak należy. Niestety nie wiem co powinienem podać jako daną wejściową. Help plisss smile.gif

Pozdrawiam i dziękuję,
woolkan
Seth
Co do SSLa to zauwazylem, ze jest funckja setForceDisableSSL(bool), ktora wywolana przed logowaniem powinna wylaczyc korzystanie z SSLa (ustawiona na true).


Natomiast co do niszczenia obiektu to uzyj funkcji Logout(), a potem finalize();
I powinno byc po sprawie winksmiley.jpg


A funkcja com_get_active_object() moze w tym przypadku nie zadzialac. Raz tylko mialem z nia stycznosc i tez byly podobne problemy. Ale o co dokladnie chodzilo to juz nie pamietam :/
Poza tym wywolanie tego spowoduje pobranie juz uruchomionej instancji, a w przypadku wywolania strony przez kilka osob jednoczesnie moga byc problemy.
woolkan
setForceDisableSSL(bool) miałem ustawione na off gdy próbowałem odpalić skrypt na IIS ale to nie pomagało i nadal się nie łączył z serwerem.

Logout i finalize też już uzywam i z nimi czy bez nich po odświeżeniu okna przegladarki z załadowanym plikiem skryptu strona ładuje się w nieskończoność i jedynym ratunkiem wtedy jest restart apacha sad.gif
Prawdę mówiąc nie wiem co jest grane sad.gif właśnie istaluje apacha z php na innym kompie i zobaczymy czy tam też będzie ten problem.
Jakbyś miał jeszcze jakieś pomysły bądź obserwacje smile.gif to będę wdzięczny za wszelką pomoc smile.gif


Dziękuję i pozdrawiam,
woolkan
Seth
Jutro sprawdze instalujac u siebie COMa ale jeszcze sprawdz czy po finalize jak dasz unset($vtApi); to czy to zadziala.
woolkan
niestety unset($vtApi) nie pomogło. Próbowałem też tak jak jest w przykładach w manualu php dać na końcu $vtApi = null; i też lipton sad.gif w dalszym ciągu jest problem z pnownym załadowaniem apacha a jedyny ratunek to restart apacha.

Sprawdzałem na drugim kompie na apachu2.2.3 bez ssl i lipton. nie pomaga ustawienie $vtApi->setDisableSSL("on") - wogóle się nie loguje na serwer. Dodatkowo problem z ponownym uruchomieniem skryptu jest taki sam.. czyli strona ładuje się w nieskończoność i jedyny ratunek to restart apacha

Dziękuję i pozdrawiam,
woolkan



-------- EDIT--------

i jak Seth? udało Ci się odpalić?

THX i pozdrawiam,
woolkan
jarek_bolo
Witam,

Minęło 8 lat, może coś w technologii WAMP<->COM się posunęło do przodu.

Mam dokładnie podobny problem. Również muszę połączyć się z pewnym system transakcyjnym, którego API jest bardzo podobne to powyższego.

Posiadam bibliotekę API w formie pliku *.dll i kurcze nie mogę zmusić PHP/Apacha do pracy z nią za pośrednictwem COMa.
Dodam, że z poziomu CLI skrypt działa. Wywołuję funkcję Login() i otrzymuję spodziewany zwrot informacji w postaci ciągu XML.

Biblioteka na pewno działa, bo również są przykłady dla innych języków i działają.
Bibliotekę zarejestrowałem w systemie komendą REGSVR32.

Wnioskuję z tego, że mam coś źle skonfigurowane w Apachu, ale co? Po uruchomieniu skryptu przez przeglądarkę trwa jego dłuuuga praca, a następnie pojawia się strona z błędem serwera 500.

Dodam, że próbowałem uruchamiać skrypt pod PHP działającym jako moduł Apacha, a teraz jako FastCGI i niestety efekty te same.


Ktoś coś poradzi?
CuteOne
Testowałeś dostęp COM na czymś innym niż Twoje API?
  1. <?php
  2. error_reporting('E_ALL');
  3. $wshShell = new COM("WScript.Shell");
  4. $WshShell->Run("cmd /C notepad.exe", 3, false);
  5. var_dump($wshShell);
  6. ?>


Jeżeli powyższy skrypt zadziała, to napisz (dokładnie) jaką komendą zarejestrowałeś bibliotekę
jarek_bolo
Cytat(CuteOne @ 25.08.2014, 11:40:44 ) *
Testowałeś dostęp COM na czymś innym niż Twoje API?
  1. <?php
  2. error_reporting('E_ALL');
  3. $wshShell = new COM("WScript.Shell");
  4. $WshShell->Run("cmd /C notepad.exe", 3, false);
  5. var_dump($wshShell);
  6. ?>


Jeżeli powyższy skrypt zadziała, to napisz (dokładnie) jaką komendą zarejestrowałeś bibliotekę

Niestety nic się nie dzieje. Zarówno w CLI, ani w przeglądarce żadnego efektu nie widzę uruchamiając powyższy kod.
EDIT:
Aa widzisz smile.gif Masz literówkę w zmiennej WshShell smile.gif Robiąc kopiuj-wklej nie zadziałało dlatego.
Po ujednoliceniu nazw zmiennych efekt działania jest taki:
W CLI: otworzyło się okno konsoli, a następnie Notatnik się uruchomił.
W przeglądarece: wyświetlony został tekst NULL.

Bibliotekę *.dll z API rejestrowałem poprzez uruchomienie CMD na prawach Administratora i wpisanie REGSVR32 nazwa-pliku.dll
Po wciśnięciu Enter wyskoczyło okno dialogowe informujące, że z sukcesem udało się przeprowadzić operację.
Sprawdzałem następnie w Rejestrze Windowsa i na pozycji HKEY_LOCAL_MACHINE\SOFTWARE\Classes\jest-nazwa-klasy-którą-zarejestrowałem
CuteOne
Sprawdź REGSVR32 /u nazwa-pliku.dll
jarek_bolo
Cytat(CuteOne @ 25.08.2014, 12:22:14 ) *
Sprawdź REGSVR32 /u nazwa-pliku.dll

Uruchomienie tej komendy powiodło się (takie okno dialogowe wyskoczyło). Dodatkowo nastąpiło usunięcie wpisu w rejestrze, który wyżej podałem.

Teraz wywołanie tej biblioteki API zarówno z CLI jak i z przeglądarki zwraca błąd o niezarejestrowanej klasie:
Kod
exception 'com_exception' with message 'Failed to create COM object `{CE92C3B9...9170AEF7F}': Klasa niezarejestrowana. ' in C:\wamp\www\backoffice\index.php:6 Stack trace: #0 C:\wamp\www\backoffice\index.php(6): com->com('{CE92C3B9...') #1 {main}


I znowu wracam do tematu smile.gif

COM, który chciałem używać działa już mi i łączę się pięknie z serwerem poprzez API udostępniane jako DLL.

Teraz mam problem z Event Handlerem :/

To API posiada interfejs dla 3 eventów, OnServerConnect, OnServerDisconnect oraz OnNewData.
Zgodnie z dokumentacją PHP do zarejestrowania obiektu odpowiadającego za gadanie z Event Handlerami COMa używam tej funkcji: com_event_sink($COM_Object, $Event_Handler_Object, 'Interfejs_Eventow_COM')

Całość wygląda tak:
  1. class ApiEventSinker {
  2. private $terminated = false;
  3. private $data = '';
  4.  
  5. public function OnServerConnect() {
  6. }
  7.  
  8. public function OnServerDisconnect() {
  9. $this->terminated = true;
  10. }
  11.  
  12. public function OnNewData($data) {
  13. if (!empty($data)) {
  14. $this->data = $data;
  15. return true;
  16. }
  17. return false;
  18. }
  19.  
  20. public function IsConnectionLost() {
  21. return $this->terminated;
  22. }
  23.  
  24. public function GetData() {
  25. return $this->data;
  26. }
  27. }
  28.  
  29. try {
  30. $api = new COM("API.Class", null, CP_UTF8);
  31. $login_status = $api->Login('adres', port, 'login', 'haslo');
  32. echo $login_status;
  33.  
  34. $subscriptions[] = null;
  35. $response = '';
  36. $subscriptions[] = $api->Subscribe('<CRITERIA><ORDERS/></CRITERIA>', $response);
  37. echo "\n\n".'Odpowiedź z subskrypcji: '.$response."\n\n}";
  38. print_r($subscriptions);
  39.  
  40. $apiEvents = new ApiEventSinker();
  41.  
  42. if (!com_event_sink($api, $apiEvents, 'API.Class.events')) {
  43. die ('Nie udało się stowrzyć handlera do Eventów');
  44. }
  45.  
  46. $data = '';
  47. do {
  48. if ($apiEvents->OnNewData($data)) {
  49. echo $apiEvents->GetData();
  50. }
  51. if ($apiEvents->IsConnectionLost()) {
  52. echo 'Polaczenie zerwane';
  53. break;
  54. }
  55. } while (true);
  56.  
  57. $api->Logout();
  58.  
  59. } catch (com_exception $e) {
  60. echo $e;
  61. }


Odpalam powyższy skrypt w konsoli. COM działa, dokonuje się subskrypcja, ale dodawanie wszelkich nowych zleceń do systemu nie powoduje przepływu eventa o tym zdarzeniu (nowe zleceni) do skryptu, nic się nie dzieje, skrypt cały czas siedzi w pętli while().

Jeśli tego nie przeskoczę będę musiał odpalić VisualStudio i niestety sięgnąć po C# czego wolałbym uniknąć.
CuteOne
Spróbuj przenieść to "do {" do linii 33 lub 36
jarek_bolo
Cytat(CuteOne @ 18.05.2015, 10:09:19 ) *
Spróbuj przenieść to "do {" do linii 33 lub 36

Dzięki za zainteresowanie.

Nie można subskrypcji odpalać w pętli. Każde wywołanie metody Subscribe powoduje założenie nowej subskrypcji na serwerze o danym ID zwracanym przez metodę Subscribe.
Tu błąd moim zdaniem nie leży.

Jest dołączony przykład w C# do tego API. Odpaliłem Visual Studio i wrzuciłem ten przykład jak również podpiąłem DLLkę z API do Projektu i po skompilowaniu wszystko działa. Ale ujawniły się dodatkowe składowe całego API o których w dokumentacji nic nie pisze :/
Główna klasa API posiada składowe typy "virtual event" do których w przykładzie załączonym przypisywane są instancje EventHandlerów o typie "delegate", które jako argument przyjmują nazwę metody zaimplementowanej w klasie korzystającej z API, która to metoda ma właśnie event odebrać. W bibliotece API jest jeszcze jakaś "sealed" klasa jako SinkHelper.

Czy z poziomu PHP można mieć dostęp do tak skomplikowanych struktur obiektu COM questionmark.gif Pojęcia nie mam.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.