{"id":13405369,"url":"https://github.com/veewee/soap-client","last_synced_at":"2025-03-14T09:32:49.347Z","repository":{"id":145901340,"uuid":"61907909","full_name":"veewee/soap-client","owner":"veewee","description":"A general purpose SOAP client for PHP","archived":false,"fork":true,"pushed_at":"2024-10-24T05:08:44.000Z","size":1348,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-24T22:55:58.216Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"phpro/soap-client","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/veewee.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-06-24T19:34:17.000Z","updated_at":"2021-08-27T22:39:11.000Z","dependencies_parsed_at":"2023-09-29T08:33:03.581Z","dependency_job_id":null,"html_url":"https://github.com/veewee/soap-client","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veewee%2Fsoap-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veewee%2Fsoap-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veewee%2Fsoap-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veewee%2Fsoap-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/veewee","download_url":"https://codeload.github.com/veewee/soap-client/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221454085,"owners_count":16824602,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T19:01:59.984Z","updated_at":"2024-10-25T19:32:07.715Z","avatar_url":"https://github.com/veewee.png","language":"PHP","funding_links":[],"categories":["PHP"],"sub_categories":[],"readme":"[![Build status](https://api.travis-ci.org/phpro/soap-client.svg)](http://travis-ci.org/phpro/soap-client)\n[![Installs](https://img.shields.io/packagist/dt/phpro/soap-client.svg)](https://packagist.org/packages/phpro/soap-client/stats)\n[![Packagist](https://img.shields.io/packagist/v/phpro/soap-client.svg)](https://packagist.org/packages/phpro/soap-client)\n\n# General purpose PHP SOAP-client\n\nSick and tired of building crappy SOAP implementations?\n This package aims to help you with some common SOAP integration pains in PHP.\n It's goal is to make integrating with SOAP fun again!\n Let's inspect some of the pains that are solved by this package:\n \nBy default the SoapClient works with a mix of arrays, stdClasses and other scalar types. \n This is not a good practice in a modern OOP world because:\n \n- It makes your code hard to test.\n- It breaks Code Completion\n- It is hard to track changes in the response and request objects.\n- The content of a result is never explicit.\n \nTo solve the above problems, this package will force you into using Value-objects for Requests and Responses.\n We know that maintaining these value-objects can be a load of work. \n No worries! There are some commandline tools available that will help you with generating a good base to start with.\n Because the SoapClient will need a classmap of WSDL to PHP Classes, there is also a classmap generator available.\n This will surely safe you a lot of time!\n By adding SOAP type converters, it is possible to transform the values of a specific SOAP type from/to a PHP type.\n The package comes included with some basic transformers for date and datetime.\n On, top of that, it is very easy to create your own transformers.\n \nAnother problem is that the native SoapClient works with a lot of magic methods.\n It is hard to debug these magic methods hence there is no code completion.\n Both SOAP and implementation methods are on the same object.\n \nThis package will force you into wrapping a SoapClient into your own Client.\n You can choose to only expose the methods you need. \n It will always be clear to the developer what's in your client, how it works and what it returns.\n We even provided a base Client for you to use with some common used methods for debugging, authentication and an event system.\n \nIn lots of SOAP integrations the logging, caching and Soap calls are in the same method.\n This makes your code hard to read and dependent on other classes / packages.\n\nIt is important keep your code clean. This is why we added an event-listener to your Soap client.\n You can hook in at every important step of the SOAP flow.\n This way it is possible to add logging, caching and error handling with event subscribers. \n Pretty cool right?!\n \nTesting webservices is hard! \n That is Why this package is fully compatible with [php-vcr](http://php-vcr.github.io/).\n Testing your SOAP client will be very fast and without any errors at the 3th party side of the integration. \n \nLast but not least, we want to make it easy for you to configure your SoapClient.\n That is why we included a ClientBuilder on which you can configure your custom Client.\n You want some other settings during development and in production? \n No problem! Sit back and let the ClientBuilder handle your Client initialisation.\n \nGreat, you made it so far! Let's find out how this module works:\n \n## Installation\n\n```sh\n$ composer require phpro/soap-client\n```\n\n## Creating your custom client\n\nThe first thing you need to do is creating your own client.\n We provided a base Client class which already has some basic features.\n An example of your custom Client looks like this:\n\n```php\nclass YourClient extends Client\n{\n    /**\n     * @param RequestInterface $request\n     *\n     * @return ResultInterface\n     * @throws \\SoapFault\n     */\n    public function helloWorld(RequestInterface $request)\n    {\n        return $this-\u003ecall('HelloWorld', $request);\n    }\n}\n```\n\nAs you can see, this custom client extends the `Client` class.\n It is also possible to implement the `ClientInterface`.\n This means you will also have to create a ClientFactory which can instantiate your custom Client.\n The SoapClient is injected inside your `YourClient` class and will not be accessible to the outside world.\n \nThe methods of the class are explicitly defined and have explicit parameters and return types.\n Request value-objects that are passed to the `call` method, MUST implement the `RequestInterface`.\n SOAP responses can have 2 types: `ResultProviderInterface` or `ResultInterface`.\n The `ResultProviderInterface` can be used if the response type is wrapping a `ResultInterface`.\n The `call` method will initailize the SOAP call and trigger the subscribed event listeners.\n\n \n## Generating Value-objects\n\nBasic value-objects can be generated automatically.\n\n```sh\n$ soap-client generate:types --wsdl=\u003cwsdl\u003e [--namespace=\u003cnamespace\u003e] \u003cdestination\u003e\n\nArguments:\n  destination                  Destination folder\n\nOptions:\n      --wsdl=WSDL              The WSDL on which you base the types\n      --namespace=NAMESPACE    Resulting namespace\n```\n\nThis generator will read all XSD types from the provided WSDL and convert it to PHP classes.\n You can specify a namespace and a location where the classes will be stored.\n The properties from the XSD will be added as private properties to the value-objects.\n When the classes already exist, a patch operation is performed and a backup file is created. \n This way your custom code will always remain available.\n\nKeep in mind that the WSDL must provide all XSD types for the generation of value-objects.\n Some exotic SOAP services don't provide much information. For example: they will return an XML string which needs to be parsed manually.\n These WSDLs can only be parsed as far as the XSD information goes.\n Al other information needs to be added manually, or by a custom class generator.\n\nWhen the value objects are generated, you will still need to customize them.\n For example by adding the required interfaces:\n\n```php\nclass HelloWorldRequest implements RequestInterface\n{\n    public function __construct($name) {\n        $this-\u003ename = $name\n    }\n\n    // Generated code\n}\n\nclass HelloWorldResponse implements ResponseProviderInterface\n{\n    // Generated code\n    \n    public function getResponse()\n    {\n        return $this-\u003egreeting;\n    }\n}\n\nclass Greeting implements ResponseInterface\n{\n    // Generated code\n    \n    public function getGreeting()\n    {\n        return $this-\u003egreeting;\n    }\n}\n\n``` \n\n## Generating class maps\n\nWhen the value-objects are generated, we need to tell SOAP about how the PHP classes are mapped to the XSD types.\n This is done by a class map, which can be a really boring manual task.\n Luckily a class map generator is added, which you can use to parse the classmap from the WSDL.\n\n```sh\n$ soap-client generate:classmap --wsdl=\u003cwsdl\u003e [--namespace=\u003cnamespace\u003e]\n\nOptions:\n      --wsdl=WSDL              The WSDL on which you base the types\n      --namespace=NAMESPACE    Resulting namespace\n```\n\nThis command will generate a class map and display it on the screen.\n You will just need to copy it and next paste it in the `ClientBuilder`.\n \nExample output:\n\n```php\nreturn new ClassMapCollection(\n    [\n        new ClassMap('HelloWorldRequest', \\HelloWorldRequest::class),\n        new ClassMap('HelloWorldResponse', \\HelloWorldResponse::class),\n        new ClassMap('Greeting', \\Greeting::class),\n    ]\n);\n```\n\n## Convert SOAP types\n\nSome exotic XSD types are hard to transform to PHP objects.\n A typical example are dates: some people like it as a timestamp, some want it as a DateTime, ...\n By adding custom TypeConverters, it is possible to convert a WSDL type to / from a PHP type.\n \nThese TypeConverters are added by default:\n\n- DateTimeTypeConverter \n- DateTypeConverter\n\nYou can also create your own converter by implementing the `TypeConverterInterface`. For example:\n\n```php\nclass MyCustomConverter implements TypeConverterInterface\n{\n    // Implement methods...\n}\n```\n \n## Basic Usage\n\nNow that we explained all parts of your new SoapClient, it is time to interact with it.\n Take a look at following snippet:\n\n```php\n$wsdl = 'http://path.to/your.wsdl';\n$clientFactory = new ClientFactory(YourClient::class);\n$soapOptions = [\n    'cache_wsdl' =\u003e WSDL_CACHE_NONE\n];\n\n$clientBuilder = new ClientBuilder($clientFactory, $wsdl, $soapOptions);\n$clientBuilder-\u003ewithLogger(new Logger());\n$clientBuilder-\u003ewithEventDispatcher(new EventDispatcher());\n$clientBuilder-\u003eaddClassMap(new ClassMap('WsdlType', PhpType::class));\n$clientBuilder-\u003eaddTypeConverter(new DateTimeTypeConverter());\n$client = $clientBuilder-\u003ebuild();\n\n$response = $client-\u003ehelloWorld(new HelloWorldRequest('name'));\necho $response-\u003egetGreeting();\n```\n\nIn the first part of the snippet you can see the global configuration of your own SOAP client.\n The `YourClient` class will be instantiated by a `ClientFactory`, which is responsible for injecting the client dependencies.\n It is possible to use the same Client with different WSDL endpoints and SOAP options.\n This makes it easy for changing between environments.\n \nNext, the client will be configured by the `ClientBuilder`.\n As you can see it is possible to add a Logger, EventDispatcher, Classmaps and TypeConverters.\n This makes the Soap client fully configurable.\n\nIn the last part of the snippet you can see how the client works.\n It will use the generated value-objects to call the `RequestInterface` on the SoapClient.\n As a result the `ResultProviderInterface` will return the actual `ResultInterface` which contains the `getGreeting()` method.\n Pretty readable right?\n\n## Hooking in with events\n\nThe `Client` class has a build-in EventDispatcher.\n It will trigger events at all important phases of the SOAP call: \n\n- Events::REQUEST (RequestEvent)\n- Events::RESPONSE (ResponseEvent)\n- Events::FAULT (FaultEvent)\n\nYou can subscribe your own listeners to the configured `EventDispatcher`. For example:\n\n```php\nclass ResponseFailedSubscriber implements SubscriberInterface\n{\n    // implement interface\n}\n\n$dispatcher-\u003eaddSubscriber(new ResponseFailedSubscriber());\n```\n\nThis package ships with some default subscriber plugins:\n\n### Logger plugin\n\nThe logger plugin is activated automatically when you attach a `LoggerInterface` to the `ClientBuilder`.\n It will hook in to the Request, Response and Fault event and will log every step of the SOAP process.\n No more code pollution for logging!\n\n\n### Caching plugin\n\nTODO: caching is sadly not part of this project yet. Want to help out? \n\n\n## Testing\n\nAs mentioned earlier, it is very easy to integrate this project with [php-vcr](http://php-vcr.github.io/).\n This makes it possible to created fixtures of all your SOAP calls.\n By loading the fixtures, no actual calls will be done to the SOAP endpoint.\n This will make your tests fast, deterministic and accurate!\n Her is an example of a PHPUnit test:\n \n```php\n/**\n * @test\n * @vcr my-fixture-file.yml\n *\n */\nfunction it_should_greet()\n{\n    $response = $this-\u003eclient-\u003ehelloWorld(new HelloWorldRequest('name'));\n    $this-\u003eassertEquals('Hello name', $response-\u003egetGreeting());\n}\n```\n\nThe first time you run this test, a fixtures file `my-fixture-file.yml` will be created.\n The second time, this file will be used instead of running actual requests.\n Test it out, you will love it!\n \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fveewee%2Fsoap-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fveewee%2Fsoap-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fveewee%2Fsoap-client/lists"}