Skip to Content
h3. Purpose   One of the paradigms of modern architecture is service orientation (SOA) with it’s SAP flavour ESA (enterprise service architecture). An important principle of SOA is implementation transparency, i.e. it doesn’t matter in which language a service is being implemented. This allows to combine services from different specialised environments into composite applications or processes.   PHP is a scripting language with an always growing userbase having its strenghts in a number of areas, in which it can complement ABAP well (e.g. xml schema validation, small footprint graphics manipulation, cryptology, …) Integrating PHP and ABAP therefore adds a valuable opportunity for those creating state-of-the-art solutions around the Netweaver platform.   In this weblog I’ll give a simple tutorial to show how to make use of webservices technologies to integrate PHP and ABAP. In my opinion the features of webservices and SOAP make the use of the good old PHPRFC library – which did such a good job for many years, obsolet. One interface technology less.   h3. Prerequisites    The examples shown here require ABAP WAS 6.40+ and PHP 5.x.  The soap libraries in PHP are not enabled by default, so we have to enable them by adding extension=php_soap.dll  to the php.ini file. For development we don’t want the WSDLs to be cached once downloaded so we have to set soap.wsdl_cache_enabled=0  in php.ini.  h3. Calling an ABAP webservice from PHP   First we have to create the webservice in ABAP. We create a very simple webservice, accepting one input parameter and returning a parameter based on it. So, we create a function module ZTW_WS1:    FUNCTION ZTW_FUB1. *”——————————————————————— *”*”Lokale Schnittstelle: *”  IMPORTING *”     VALUE(P_IN) TYPE  STRING *”  EXPORTING *”     VALUE(P_OUT) TYPE  STRING *”———————————————————————    concatenate ‘ABAP says: Hello’ space p_in into p_out separated by space. concatenate p_out ‘!’ into p_out.  ENDFUNCTION.   This is probably the most simple function module to test the functionality. It expects a name, say +Sue+, and returns +ABAP says: Hello Sue!+ We _remote-enable_, save and activate it. Next we create a webservice based on it. Since this is a bit different for different versions of ABAP WAS, please consult the documentation for it. Regardles of the version it’s quiet simple, just right-click the function module and find the appropriate action or create a new object of type webservice interface. Do not forget to release the service for the soap runtime. When everything is set up, we get the WSDL (webservice description language; ‘the service description’) at the following address:  http://tonysub:8000/sap/bc/srt/rfc/sap/ZTW_WS1?sap-client=100&wsdl=1.1   where tonysub is the name of our ABAP host. Just view it in your browser if you have never seen one 🙂  The next thing is to create a client in PHP to consume this service. SOAP support is built-in for PHP 5.x so we can immediately start to code our client:    $wsdlurl =”http://tonysub:8000/sap/bc/srt/rfc/sap/ZTW_WS1?sap-client=100&wsdl=1.1“; $login = “bcuser”; $password = “minisap”; ?>         Your name:   Debug? :       $client = new SoapClient($wsdlurl,  array(‘login’ => $login,  ‘password’ => $password,  ‘trace’ => true,  ‘exceptions’ => true));   try {  echo $client->ZtwFub1(array(‘PIn’ => $name))-> POut;   }   catch (SoapFault $e) {      echo ‘Caught an Error:  (‘ . $e->faultcode . ‘) – ‘ . $e->faultstring;   }    if(isset($debug)) {      echo “—- \n”;  echo “Request :\n”.htmlspecialchars($client->__getLastRequest()) .”\n”;  echo “Response:\n”.htmlspecialchars($client->__getLastResponse()).”\n”;  echo ” “;  } } ?>    There’s ‘a lot’ of coding masking the simplicity of the webservice call, so here’s the crucial parts again:   The constructor:     $client = new SoapClient($wsdlurl,  array(‘login’ => $login,  ‘password’ => $password,  ‘trace’ => true,  ‘exceptions’ => true));   And the actual service call(and display of the result):     echo $client->ZtwFub1(array(‘PIn’ => $name))->POut;   The rest of the coding shows  ** an HTML form letting you enter your name and decide if you want to see debugging information  ** SOAP error handling  ** debugging of the SOAP communication   Here is what we’ve got so far. An input screen to input your name:imageAn the result showing the answer of the webserviceimage h3. Calling a PHP webservice from ABAP    First we create a webservice in PHP. This is not so easy as one might expect from PHP. The reason for this is that using the standard SOAP functions you need a WSDL first to instanciate a webservice. There are libraries on the internet allowing to autogenerate a WSDL based on some PHP functions but those libraries are not too elaborate yet. One good solution is the one provided by   Mainly we adopt some namespaces to point to our own namespace +urn:tonysub/soapexample1+ and the SOAP:address location to point at our webservice at http://tonysub/ws/soapserver1.php. We save this as soapserver1.wsdl to our webdirectory.  Havin the WSDL it’s very easy to create the webservice in PHP     function ZtwFub1($name) {  return (array(POut => “PHP says: Hello ” . $name->PIn . “!”)); }  $server = new SoapServer(“soapserver1.wsdl”); $server->addFunction(“ZtwFub1”); $server->handle();  ?>    That’s the PHP webservice. We could test it by simply pointing the client above to the new WSDL location, i.e. http://tonysub/ws/soapserver1.wsdl (and clearing login an password for this example). But we quickly move on to test it from the ABAP side. We go to SE80 again and create a so called webservice proxy obbject using the same WSDL. We follow the wizard and get a proxy object, e.g. ZTW_CO_ZTW_WSX. DDIC structures for the input and and output parameters are created, here ZTW_ZTW_FUB1 and ZTW_ZTW_FUB1. Finally we have to go to transaction LPCONFIG and create a logical port for our proxy object. So, the only thing left to do is write a report to make use of this proxy object.     *&——————————————————————– * *& Report  ZTW_CALL_WS *& *&——————————————————————– * *& *& *&——————————————————————– *  REPORT  ZTW_CALL_WS.  data: my_client type ref to ztw_co_ztw_wsx,       my_result type ztw_ztw_fub1response,       my_input  type ztw_ztw_fub1.  parameters: my_name(20) type c.  my_input-pin = my_name.  create object my_client.  call method my_client->ZTW_FUB1                 exporting INPUT  = my_input                 importing OUTPUT = my_result.    write: / my_result-pout.  Voilá, we end up with the following: An input screen to enter a name imageAn the result showing the answer of the PHP webserviceimage
To report this post you need to login first.

17 Comments

You must be Logged on to comment or reply to a post.

  1. Alvaro Tejada Galindo
    Thanx a lot Anton, just what i needed in order to start with some WebServices. A simple example is more usefull than a thousand tutorials. Great job!

    Greetings,

    Blag.

    (0) 
  2. Sumith Rajagopalan
    This is a very good work and a much needed one for me.  Just want to comment that you can still use NuSOAP with PHP 5.0.  You will have to rename the soap class in NuSOAP to something like ‘ns_soap’ or the like so that it will not create a conflict between the standard ‘soap’ class provided by PHP.

    Regards,
    Sumith

    (0) 
  3. Claudia Cardenas
    Hi!!

    I don´t speak and write english, I sorry!.

    I Created a WS in ABAP, equality your indications and I created the aplication in PHP, but it not generates the consuming… not continued where the line next:

    $login, ‘password’ => $password, ‘trace’ => true, ‘exceptions’ => true)); try { echo $client->ZtwFub1(array(‘P_IN’ => $name))->P_Out; } catch (SoapFault $e) { echo ‘Caught an Error: [‘ . $e->faultcode . ‘] – ‘ . $e->faultstring; } if(isset($debug)) { echo “
    ——————————————————————————–

    \n”;
         echo “Request :\n”.htmlspecialchars($client->__getLastRequest()) .”\n”;
         echo “Response:\n”.htmlspecialchars($client->__getLastResponse()).”\n”;
         echo “
    “; } } ?>

    the characteristic in php.ini too they were modified. attempt to make also with “nusoap” and does not work. It can give a hand me!

    Thank You!!!

    (0) 
  4. Codrut Bila
    As a new bee in ABAP I wonder whether minisap is able to work as a WAS, and if yes, how the ABAP function module can be set as WebService.
    Regards!
    (0) 
    1. Anton Wenzelhuemer Post author
      Hi Codrut,

      the blog states the requirement as 6.40+; AFAIK ‘minisap’ was the name of the demo versions accompanying ABAP programming books some years ago, the last of which was a 4.6 system. Later test systems were (and still) are available for download at SDN as trial versions.
      so, 4.6 systems do not support webservices at all, 6.20 systems have a very early version of the SOAP runtime (webservice environment), which is no fun to work with, 6.40+ systems support webservices with growing functionality and maturity.

      if you have your suzitable system set up the rest is fairly easy. goto SE80, find the function module you want to expose, right click it and find the menu entry to create a webservice; you’ll be supported by a wizard. if you’re done with that, you got to configure your service which differs from version to version; see the documentation for that and join the SOA forum for advanced questions (after you searched for solutions yourself 😉 )

      hope it helps,
      anton

      (0) 
      1. Codrut Bila
        Hi Anton,
        First of all thx for being so fast and accurate in your explanations.
        …well, I succeeded in creating the web service [I named it ZHELLO] in SAP Netweaver 7.0 [Abap Trial Version], however, I don’t know how to find out the name of the ABAP host, in order to get the ‘service description’ in the browser [http://……].
        So, please, any suggestion is very welcome.
        Kind Regards!
        (0) 
        1. Anton Wenzelhuemer Post author
          depending on your patchlevel it’s either a push button above the services in transaction WSADMIN or a link to the WSDL within the details of a service in transaction SOAMANAGER.
          (0) 
    1. Anton Wenzelhuemer Post author
      Hi Federico,

      I think, your problem is that you search the content in the header instead of the response body.

      Instead of re-reading my own old blog I quickly made you a working example of reading T005. Just try it out and tell me if it works for you:

      The function module:


      FUNCTION ZTW_COUNTRY.
      *"----------------------------------------------------------------------
      *"*"Lokale Schnittstelle:
      *" EXPORTING
      *" VALUE(TABLE_OF_COUNTRIES) TYPE ZTW_CTRS
      *"----------------------------------------------------------------------
      * ZTW_CTRS has line type V_T005

      data: lt_countries type ztw_ctrs.

      select * from T005 into corresponding fields of table lt_countries up to 10 rows.
      table_of_countries = lt_countries.

      ENDFUNCTION.

      create a webservice from it and call it in PHP like follows:


      $wsdlurl = "(your WSDL URL)";

      $clientparams = array(
      'login' => "(your SAP user)",
      'password' => "(your SAP user's password)",
      'proxy_host' => "ip of your proxy if needed",
      'proxy_port' => 1234);
      //numerical! port of your proxy if needed

      $soapClient =
      new SoapClient($wsdlurl, $clientparams);

      try {
      $ret =
      $soapClient->__call("ZtwCountry", array());

      } catch (SoapFault $fault) {
      echo "arghh";
      }
      if (isset($ret)) {
      // var_dump($ret->TableOfCountries);
      foreach($ret->TableOfCountries->item as $entry){
      echo $entry->Land1 . "::"
      . $entry->Landa . "\n";
      }
      }
      ?>

      hope you get the formatting right, it’s a bit of a pain here. But it should give you the required table.

      regards, anton

      (0) 
      1. Federico Gulla
        Hi Anton !

        Was precisely the solution that was implemented, but did not work with WS made by a supplier outside SAP.
        I asked the provider to generate the WS you put as an example and it worked fine.
        Taking your example, the supplier made the corrections in their WS to return data as a table type and now it works.
        Thanks for the help, example and your time.

        Regards, Federico

        (0) 
  5. Jayanta Narayan Choudhuri

    PHP SOAPCLIENT works well for the default sap-client  and ONLY WSDL 1.1;

    if the user password is for a different client seems to fail

    Say 300 and 600 are 2 SAP-clients and 300 is default

    WSDL for 600 works but with a user belonging to 600

    I cannot login as there is no provision for sap-client in

    $client = new SoapClient(

    $wsdl,

    array( “login” => $user,

             “password” => $passwd ) );

    Works fine if user belongs to 300(default)      

    ===================================================

    PHP SoapClient Does NOT support WSDL 2.0 as generated by ECC6 Wizard

    It only supports WSDL 1.1 as prevailed in 4.7 era; luckily still supported

    Read

    http://phpwebservices.blogspot.in/2008/01/what-is-missing-in-php-soap-extension.html

    http://wso2.com/products/web-services-framework/php/

    WS02 PHP Soap does support WSDL 2.0 but I think it best

    a) to stick to SAP PHP RFC

    b) use SOAPCLIENT WSDL 1.1 route

    It is time for a official SAP PHP that is as good as JCO!

    Is SAP Listening?

    (0) 
    1. Anton Wenzelhuemer Post author

      Hi Jay,

      if you use the URL-parameter &(?)sap-client=nnn in your service call you can access the service on  a specific SAP client.

      I can’t re-check your info right now, but I know that I have called numerous webservices using a PHP client against any ECC6 system version. It always worked easily. So, either 2.0 is not the default version of generated services or the soapclient of a reasonable recent PHP client supports 2.0. Will re-check when time permits.

      regards, anton

      (0) 

Leave a Reply