The following table shows a brief comparison between all possibilities to connect to SAP from PHP, that I have come up so far. Each has it's own pros and cons, so to think carefully before making your choice.
You should definitely consult the SAP team too, as they will need to get involved in most cases. Be warned, that there are very controversary oppinions upon security: many SAP consultants do not advise to call internal logic (i.e. existing RFC function modules or BAPIs) or read internal tables from an external application.
Other important things to be thought of are batch processing and error handling. In a synchronous API (like oData or SOAP webservices), the result of an operation is given to the client immediately making the client (your PHP app) responsible for error handling. With asynchronous communication it's more a fire-and-forget from the point of view of the client: the SAP server would have to deal with errors, inconsistent data, etc. In this case, the built-in tools for IDoc management come in handy.
oData | OpenSQL via ADT | SOAP RFC | JSON RPC | NWRFC | IDoc files | IDocs+SOAP | |
---|---|---|---|---|---|---|---|
Webservice | ✔ | ✔ | ✔ | ✔ | ✔ | ||
Format | XML/JSON | SQL+XML | XML | JSON | PHP-API | XML/text | XML |
Synchronous reading | ✔ | ✔ | ✔ | ✔ | ✔ | ||
Synchronous writing | ✔ | ✔ | ✔ | ✔ | |||
Batch processing | ✔ | ✔ | |||||
Requires third-party SAP add-on | ✔ | ||||||
Requires ABAP programming | ✔ | ||||||
Requires SAP configuration | ✔ | ✔ | ✔ | ✔ | ✔ | ||
Requires SAP libs on webserver | ✔ | ||||||
Monitoring/Clearing in SAP | ✔ | ✔ |
In any case, be prepared not to find a ready-to-use generic API on SAP side. For most more-or-less serious usecases a conciderable amount configuration or even programming will be necessary in SAP! This means, you will definitely need the help of the company's SAP team when building your communication interface between SAP and PHP.
oData REST webservices
According to SAP itself, the most modern and currently recommended way to connect anything to the SAP world are RESTful webserices based on the oData standard. In particular, this is the interface used by SAP Fiori web apps and the underlying SAPUI5 and OpenUI5 frameworks. In an nutshell, you need to implement a custom webservice for your specific task in SAP NetWeaver and consume it via PHP. Here is a simple PHP example using the guzzle HTTP client:
$client = new GuzzleHttp\Client(); $res = $client->request('GET', 'GET http://services.odata.org/TripPinRESTierService/People'); $people = json_decode($res, true)['value']; print_r($people[1]); // ["UserName" => "russellwhyte", "FirstName" => "Russell" ...]
From the point of view of software architecture, this solution is really elegant, clean and easy to handle on PHP side. The trouble is, that you will need to implement webservices for every request type in SAP NetWeaver yourself. There is nothing you can use out of the box. In the simplest case, you can reuse your BAPIs or function modules, but would still need to create corresponding metadata models for oData. However, if you want to leverage the power of oData with complex queries, filters, etc., you will probably end up with lots of ABAP coding. Even though SAP offers various code generation possibilities, there is still a lot to do manually. And the resulting webservice structure within SAP is far from simple.
If you do come to use OData with PHP, pay attention to session handling and CSRF-tokens - take a look at my article about NetWeaver CSRF-security in web services.
ADT OpenSQL console
The ABAP Development Tools (ADT) - SAP's interface for the Eclipse IDE - include a barely documented web service called datapreview
. It can perform any OpenSQL select statement and returns the result as a simple XML structure - see my article on running SQL via web service on SAP for details. This is how the SQL console in Eclipse works.
This service is a real blessing if you need to get a prototype up and running with real data. But being a development tool, it is probably not a good choice for production because of low level of access control. On the other hand, there are certain scenarios like ad-hoc reporting or configurable ETL processes, where it might save you a lot of efforts.
SOAP webservices for RFC or BAPIs
Another way to expose SAP data via webservice are SOAP services, which can be generated for any remote-accessible RFC or BAPI with a few clicks in SAP NetWeaver. While SOAP is currently (2018) far from being modern, it still works, is natively supported in PHP and requires no coding and comparatively simple configuration in SAP. Needless to say, that there are hundreds of RFCs and BAPIs ready to use right out of the box.
Apart from the service type and the syntax, the main difference to oData is, that you call your RFC function modules or BAPIs directly without a clean metadata model inbetween. For ABAP developers this might even be an advantage, as they typically know a lot about what their code does, but for someone from outside of the SAP world it's clearly more difficult to find the way to the desired functionality.
Here is a good tutorial on exposing an RFC via SOAP webservice. By the way, the example RFC used is RFC_READ_TABLE
, which would allow to read any table or view from SAP genericly - although without JOINs or complex subqueries like in the case of ADT.
Here is a very simplified example in PHP:
$sap_wsdl = "http://your_sap_system/your_service_path?wsdl"; $sap_client = new SoapClient($sap_wsdl); $res = $sap_client->RFC_READ_TABLE();
JSON-RPC for RFC modules
Don't like SOAP? There also seems to be a possibility to use JSON-RPC to call RFC-enabled function modules. You will need a custom ICF handler, however. I did not try it myself yet, but here is a detailed tutorial to start with.
NWRFC extension for PHP7
An alternative to using webservices to call RFC function modules is using a special extension for PHP. While no configuration on SAP side is required, you will need the SAP NW RFC library on your PHP server and a third-party open-source PHP extension. Here is the corresponding PHP code example (taken from the documentation of the extension):
use SAPNWRFC\Connection as SapConnection; use SAPNWRFC\Exception as SapException; $config = [ 'ashost' => 'my.sap.system.local', 'sysnr' => '00', 'client' => '123', 'user' => 'YOUR USERNAME', 'passwd' => 'YOUR PASSWORD', ]; try { $c = new SapConnection($config); $f = $c->getFunction('STFC_CHANGING'); $result = $f->invoke([ 'START_VALUE' => 0, 'COUNTER' => 1, ]); } catch(SapException $ex) { echo 'Exception: ' . $ex->getMessage() . PHP_EOL; }
IDocs as XML or text files
The most common way of communication between SAP and an external application are IDocs (short for Intermediate Document). An IDoc is a text-file representation of one or more SAP business object of a cerain type. IDocs come in two flavours: as fixed-lenght plain-text or as XML, the first being more common. IDocs have been around for ages and there are a lot of built-in IDoc types. Use SAP transaction WE60
to find out, what you can import and export via IDoc. Existing IDocs types can also be easily extended.
Using IDocs you can fairly easily build asynchronous interfaces: SAP would export required data as an IDoc file and save it somewhere and it could also read IDoc files from a specified location. In both cases, the sender of the message has no chance to know, what happened to it.
IDoc processing is generally concidered pretty slow. On the other hand, there are lot's of built-in tools in SAP, that allow monitoring, error handling, etc. IDocs are also concidered safe.
From the point of view of PHP, a typical file-based IDoc interface boils down to reading and writing text files and uploading them to an FTP server or so. Here is a good article (in german) to get you started.
IDocs via webservice
There are built-in RFC function modules to read and write IDocs, so you can configure a SOAP webservice, that would export and import IDocs. From my point of view, this would be a lot more elegant, than having a file-based interface. Although, I must admit, that I have never tried this approach so far.
To read IDocs addressed to a specific partner, use function module EDI_PARTNER_READ_COMPLETE
. For uploading IDocs there are multiple possiblities like IDOC_INBOUND_ASYNCHRONOUS
or IDOC_INBOUND_SINGLE
- see complete list with more information in the SAP documentation.
Of course, you can also access these function modules using the NWRFC connector, but if you ask me, a webservice just seems a better solution for a web application.