Autor Zpráva
Kcko
Profil
Ahoj,

pokouším se vytvořit WSDL a SoapClienta.

wsdl zde: wsdl.rjwebdesign.cz/server7.php?wsdl
wsdl jsem si nechal vygenerovat touto knihovnou: github.com/dragosprotung/php2wsdl z této primitivní testovací třídy

<?php

/**
 * Example class with @soap annotation.
 */
class Test
{

  /**
     * Adds two numbers.
     *
     * @soap
     *
     * @param float $p1
     * @param float $p2
     * @return float
     */
    public function add($p1, $p2)
    {
        return ($p1 + $p2);
    }


     /**
     * Make array.
     *
     * @param mixed $el1
     * @param mixed $el2
     * @return array
     */
    public function makeArray($el1, $el2)
    {
        return array($el1, $el2);
    }



    /**
     * @soap
     */
    public function getDayyy()
    {
        return date('j');
    }

    /**
     * @soap
     */
    public function getHour()
    {
        return date('H');
    }
    /**
     * @soap
     */
    public function getSleep($force = 1)
    {
        if ($force)
            return 'chce se nám spát';

        return 'jeste se spat nejde';
    }


}


Když se snažím volat nějakou metodu, např.

$client->add(1, 2); tak to spadne viz wsdl.rjwebdesign.cz/client-call.php
nebo když volám getDayyy() tak to nespadne ale výsledkem je NULL.


Co je špatně?


GITHUB: github.com/Kcko/wsdl
Kcko
Profil
Nechci to nijak vytahovat, nicméně, dotaz jsem položil i na StackOveflow. Nikdo neodpověděl stejně jako tady.

Je problém příliš složitý nebo jsem popsal něco nejasně?
blaaablaaa
Profil
Koukal jsi, co ti vrací __getLastResponse?
Kcko
Profil
blaaablaaa:
Ano koukal, smyslupnou odpověd (XML). Nikde tam nemám chybu o čemsi, čeho bych se mohl chytit.
V exception v message dostanu "[Client] looks like we got no XML document", což je mi k ničemu. Samotné WSDL se zdá být OK.
TomášK.
Profil *
Popsané je to celkem dobře. Zakopaný pes je zřejmě někde v té knihovně a k vyřešení by si jí někdo musel nainstalovat k sobě na server. Tím se značně sníží počet těch, kteří jsou ochotní odpovědět.

Kdybych to měl řešit, tak klienta nahradím za curl, abych tam měl o závislost méně, a pak budu zkoumat, co se děje na serveru přes ladící výpisy.
Kcko
Profil
TomášK.:
Žádnou lepší "Class2WSDL" převodní knihovnu jsem nenašel. Používá se a na Githubu nejsou žádná issue s podobným problémem.
Jakého klienta? Je to nativní třída od PHP 5.3+

Obecně s tím SOAPem jsou nějaké problémy. Když jsem zkoušel NON WSDL režim, tak mi to XML padalo podobně a musel jsem zapnout v php.ini "always populate raw post data" a to bylo jediné řešení, které jsem asi po 2h googlení našel.
A WSDL režim mi nefunguje ani s touto direktivou.

Obecně si myslím, že SOAP je pomalu mrtvý a nahrazuje ho REST, ale stejně bych to chtěl vyřešit, abych věděl.
TomášK.
Profil *
Kcko:
Já proti té knihovně nic nemám, jen jsem říkal, proč si myslím, že nikdo neodpovídá - musel bys natrefit na někoho, kdo tu knihovnu už má nebo je ochotný ji instalovat.

Pochopil jsem, že $client->add(1, 2); je kus kódu, který spustíš na klientoví, a který dá dohromady XML, které pošle na WDSL. Je-li to součást PHP, zřejmě to bude spolehlivé, ale stejně bych radějí viděl, co chodí po drátě. Odchytím tím třeba situaci, kdy mi to vrátí NULL, protože se nepovede nějaká konverze.
blaaablaaa
Profil
Kcko:
Nemelo by na serveru byt jeste tohle + nejaky autoloader?

$server->setClass('Test');
Kcko
Profil
blaaablaaa:
Taky jsem zkoušel a autoloader jsem nahradil za prosté require, s tím problém není, akorát jsem už GH neaktualizoval - výsledek stejný.

TomášK.:
Ano proto jsem založil projekt na GH a je tam composer, takže instalace je otázkou chvíle :-). Holt je to složitejší něž většina zdejších vláken typu proč mi nefunguje insert do db :-)))
blaaablaaa
Profil
Kcko:
Zkus to vygenerovat ještě v něčem jiném, nechápu tam to namespace tempuri.org + chybí tam import toho xsd, ne? (ale moc zkušeností nemám, soap používám zatím jen jako klient)
Kcko
Profil
blaaablaaa:
namespace je vcelku jedno, měl jsem svojí doménu, měl jsem localhost. Import XSD by tam byl, kdybych použil ->setClass.

V čem jiném? Zkoušel jsem 2 pofidérní skripty a další 2 třídy a pak už jsem nic rozumného nenalezl, všechno končí stejnou hláškou.

Zkoušel jsem i na různých PHP verzích (5.3/5.6/7.0/7.1), možná něco s nastavením PHP, ale to se mi moc nezdá.
WSDL struktuře moc nerozumím, okem jsem kontroloval s jiným WSDL dokumentem a bylo tam +/- všechno velmi stejné, takže nevím jak dál postupovat.
Taps
Profil
a co treba toto code.google.com/archive/p/php-wsdl-creator

to by ti nepomohlo?
Kcko
Profil
Taps:
Díky, ale tohle je moc robustní :-) a už i zastaralé.

Nakonec jsem problém vyřešil (ted před 5 min), zajímá to někoho?
Taps
Profil
Kcko:
jasně, že zajímá...rád se něčemu dalšímu novému přiučím.
Kcko
Profil
Taps i pro ostatní:
1) První problém byl v nesprávné service URI při generování WSDL (mylně jsem se domníval, že to má směřovat na nějakou URL nebo na url serveru kde to běží, omyl; musí to směřovat na adresu; kde je puštený SoapServer (tj na nějaký php soubor, kde je to zinicializované, u me to je server.php).

2) Druhý, vážnější problém: Každá metoda, která jde do vygenerovaného WSDL, která se SoapServeru nastavuje, musí být řádně zdokumentovaná a oanotovaná viz github.com/Kcko/wsdl/blob/master/class/Test.php#L51-L56 (Bez tohoto správného nastavení to fungovat nepůjde a nelze se dozvědět proč a kde je chyba, přišel jsem na to náhodou).

Původní repo jsem smazal, znovytvořil a aktualizoval a zjednodušil ukázku clienta a serveru -> github.com/Kcko/wsdl

Třeba to někomu pomůže až to bude potřebovat a bude to objevovat jako já.

Asi už to jediné co mě trápi, je že nechápu proč objekt, mezi jednotlivými voláními, který se SoapServeru nastaví (přes metodu setClass) drží výchozí hodnotu členských proměnných. Lidsky řečeno, pokud zavolám $client->metodaA(), ve které bych nastavil do členské proměnné nějakou hodnotu a pak zavolal $client->B() tak tam ta nová hodnota nebude a bude tam hodnota nastavená výchozí nebo nastavená v constructoru.


Tohle je taky vtipné (github.com/Kcko/wsdl/blob/master/class/Test.php#L84) i když má metoda nastavený výchozí parametr a při volání jej tedy neuvedete
tj. $client->getOneOrTwo(); // v klasickém php by se vrátilo 1, tady se vrátí 2
z čehož plyne, že parametry se musí explicitně uvádět, i když jsou nastaveny jako výchozí.
TomášK
Profil
Asi už to jediné co mě trápi, je že nechápu proč objekt, mezi jednotlivými voláními, který se SoapServeru nastaví (přes metodu setClass) drží výchozí hodnotu členských proměnných.
Na serveru může běžet X serverových procesů. Pokud by si proces pamatoval svůj stav, bude se to chovat nepředvídatelně (nevíš, který proces odpoví). Pokud bys nastavoval hodnotu všem, bude to docela oříšek na synchronizaci a někde by se musel skladovat ten sdílený stav. Dává mi smysl, že se to chová tak, jak píšeš.
Kcko
Profil
TomášK:
Asi tomu rozumím, chová se to jinak než klasický objekt, tedy třída pod SOAP objektem v režimu WSDL (Jakoby jednotlivé metody v objektu, byly nějakým způsobem od sebe zcela odděleny a $this tam moc nefunguje - resp to co nenastavím v __constructoru).
Když se mrkneš do toho mého (již funkčního) příkladu, tak jsem schopen díky authTokenu (vlastní proměnná) rozpoznat přihlášeného uživatele. Už ale nemám možnost jak třeba dalším metodám říci o jakého uživatele (login, authLevel atd) jde, krom toho, že bych ho přihlašoval v každé metodě, která vrací nějaká data, což je trošku divné.
blaaablaaa
Profil
Kcko:
Koukal jsi na tohle www.slideshare.net/mayflowergmbh/stateful-soap-webservices ?
Kcko
Profil
blaaablaaa:
Koukám, ale nevidím tam to na co se ptám.


Tak už vím jak na to. Stačí nastavit SoapServeru persistentní chování setPersistence(SOAP_PERSISTENCE_SESSION); (github.com/Kcko/wsdl/blob/auth/server.php#L23)
A konečně začnou v metodách fungovat přenastavené properties z jiných metod (např. v metodě login() nastavím tedy ten můj authLevel a v další metodě ho vidím změněný) :-)

Víc už to zkoumat asi nebudu. Díky všem.
quatzael
Profil
Kcko:
Já tyhle věci vůbec už neřeším přes SoapClienta, protože to má vždycky nějaký mouchy, kvůli kterým to nejde.
Nejjednodušší je to napsat ručně. Většinou nepotřebuješ zadávat ani všechna nastavení a funguje to spolehlivě.

Něco na tenhle způsob:

  $headers = array(
                        "Content-Type: text/xml;charset=UTF-8",
                        "Accept-Encoding: gzip,deflate",
                        "SOAPAction: http://tempuri.org/IIservice/$urn",
                        "Host: ws.domain.cz",
                        "User-Agent: Apache-HttpClient/4.1.1 (java 1.5)",
                        "Connection: Keep-Alive", 
                        "Content-length: ".strlen($xml)
                    );          
               

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
            curl_setopt($ch, CURLOPT_URL, "actual_wsdl_url");
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
            curl_setopt($ch, CURLOPT_TIMEOUT, 100);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); 
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);  
            
            $response = curl_exec($ch);         
             curl_close($ch);
            
              
Kcko
Profil
quatzael:
Ahoj,
tenhle topic, ale vubec nebyl o problému se SoapClientem. Byl tu problém s generováním WSDL a nějakými dalšími věcmi v SoapServeru (tj. to kam se připojuješ).

PS. Touhle zrůdností mám nahradit 1 řádek, sloužící k připojení clienta k serveru jo? Viz github.com/Kcko/wsdl/blob/master/client.php#L10
quatzael
Profil
Kcko:
Aha, ok. Každopádně, já jsem měl se SoapClientem docela neřešitelný problémy a některý WS na něm vůbec nešly zprovoznit..
blaaablaaa
Profil
quatzael:
Ja ho pouzivam na vice projektech a zatim bez problemu. Pro zajimavost, co ti tam neslo?
Kcko
Profil
quatzael, blaaablaaa:
To by mě taky zajímalo, protože co jsem si namátkou zkoušel některé free WSDL služby k testování (a že jich teda moc není), tak všechny fungovaly v pohodě.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0