General purpose PHP SOAP-client

Overview

Build status Installs Packagist

General purpose PHP SOAP-client

Sick and tired of building crappy SOAP implementations? This package aims to help you with some common SOAP integration pains in PHP. Its goal is to make integrating with SOAP fun again!

Demo

Soap Client demo

Prerequisites

You can choose what HTTP client you want to use. This package expects some PSR implementations to be present in order to be installed:

  • PSR-7: psr/http-message-implementation like nyholm/psr7 or guzzlehttp/psr7
  • PSR-17: psr/http-factory-implementation like nyholm/psr7 or guzzlehttp/psr7
  • PSR-18: psr/http-client-implementation like symfony/http-client or guzzlehttp/guzzle

Example:

$ composer require symfony/http-client nyholm/psr7

Installation

$ composer require phpro/soap-client

Scafolding Wizard

Since life is too short to read documentation, we've added a scafolding wizard which will get you communicating with your SOAP server in no time! All you need to do is:

./vendor/bin/soap-client wizard

You can customize the generated code based on the manual installation pages in the next chapter.

Getting your SOAP integration up and running

  1. Create your own SOAP client.
  2. Generate PHP classes based on SOAP types.
  3. Generate a class map
  4. Generate your own SOAP client.
  5. Generate a client factory.
  6. Use your SOAP client.
  7. Test your SOAP client.

Advanced configuration

This is a client implementation on top of php-soap. For more advanced configuration, you can check the documentation inside the php-soap packages.

Customize the code generation

Known issues

Why this soap client was made

By default, the SoapClient works with a mix of arrays, stdClasses and other scalar types. This is not a good practice in a modern OOP world because:

  • It makes your code hard to test.
  • It breaks Code Completion
  • It is hard to track changes in the response and request objects.
  • The content of a result is never explicit.

To solve the above problems, this package will force you into using Value-objects for Requests and Responses. We know that maintaining these value-objects can be a load of work. No worries! There are some commandline tools available that will help you with generating a good base to start with. Because the SoapClient will need a classmap of WSDL to PHP Classes, there is also a classmap generator available. This will surely safe you a lot of time! By adding SOAP type converters, it is possible to transform the values of a specific SOAP type from/to a PHP type. The package comes included with some basic transformers for date and datetime. On, top of that, it is very easy to create your own transformers.

Another problem is that the native SoapClient works with a lot of magic methods. It is hard to debug these magic methods hence there is no code completion. Both SOAP and implementation methods are on the same object.

This package will force you into wrapping a SoapClient into your own Client. You can choose to only expose the methods you need. It will always be clear to the developer what's in your client, how it works and what it returns. We even provided a base Client for you to use with some common used methods for debugging, authentication and an event system.

In lots of SOAP integrations, the logging, caching and Soap calls are in the same method. This makes your code hard to read and dependent on other classes / packages.

Creating a great OO SOAP client means that you'll have to create a lot of code. This can be a tedious task which can be automated. That is why we've added the tools to automatically generate the SOAP objects from the XSD scheme inside the WSDL. It is even possible to specify your own code-generation rules and code assemblers or use one of our many built-in classes.

It is important keep your code clean. Therefore, we added an event-listener to your Soap client. You can hook in at every important step of the SOAP flow. This way it is possible to add logging, validation and error handling with event subscribers. Pretty cool right?!

Implementing SOAP extensions is a real pain in the ass. It forces you to overwrite core methods of the built-in SOAP client. If you ever had to implement WSA or WSSE in SOAP, you know that there is something wrong in the core. Therefore, we made it easy for you to extend our SOAP client. You can specify which data transfer handler like e.g. Guzzle you want to use. Depending on the selected handler, you can easily add support for SOAP extensions or advanced authentication through HTTP middlewares.

Dealing with ext-soap is not for all developers. There are some nasty quirks you need to know about. Therefore, we made it possible for you to use which ever driver you want to use. By default we will still ship an ext-soap driver, but it is completely opt-in. You can use any user-land SoapClient implementation if you wrap it in our own driver interfaces.

Testing webservices is hard! This package provide some various ways of testing a SOAP service. Since the transport is HTTP based, you could use a php-vcr implementation. If you don't want to do actual HTTP calls, you could also use a custom Transport or Caller in your test cases. Testing your SOAP client will be very fast and without any errors at the 3th party side of the integration.

Last but not least, we want to make it easy for you to configure your SoapClient. That is why we included a generated ClientFactory on which you can configure your custom Client. You want some other settings during development and in production? No problem! Sit back and let the factory handle your Client initialization.

Comments
  • About sequence generation again

    About sequence generation again

    Hello,

    I have a service description like so:

    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/dynamics/2006/02/documents/QueryCriteria" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/dynamics/2006/02/documents/QueryCriteria">
        <xsd:element name="QueryCriteria" type="QueryCriteria" />
        <xsd:complexType name="QueryCriteria">
            <xsd:sequence minOccurs="1" maxOccurs="unbounded">
                <xsd:element name="CriteriaElement" type="CriteriaElement" />
            </xsd:sequence>
        </xsd:complexType>
        <xsd:complexType name="CriteriaElement">
            <xsd:sequence>
                <xsd:element name="DataSourceName" type="xsd:string" />
                <xsd:element name="FieldName" type="xsd:string" />
                <xsd:element name="Operator" type="Operator" />
                <xsd:element name="Value1" type="xsd:string" />
                <xsd:element minOccurs="0" name="Value2" type="xsd:string" />
            </xsd:sequence>
        </xsd:complexType>
        <xsd:simpleType name="Operator">
            <xsd:restriction base="xsd:string">
                <xsd:enumeration value="Equal" />
                <xsd:enumeration value="NotEqual" />
                <xsd:enumeration value="Greater" />
                <xsd:enumeration value="GreaterOrEqual" />
                <xsd:enumeration value="Less" />
                <xsd:enumeration value="LessOrEqual" />
                <xsd:enumeration value="Range" />
            </xsd:restriction>
        </xsd:simpleType>
    </xsd:schema>
    

    Using default generator I get following classes:

    <?php
    
    namespace App\Soap\Type;
    
    class QueryCriteria
    {
        /**
         * @var \App\Soap\Type\CriteriaElement
         */
        private $CriteriaElement;
    
        /**
         * @return \App\Soap\Type\CriteriaElement
         */
        public function getCriteriaElement()
        {
            return $this->CriteriaElement;
        }
    
        /**
         * @param \App\Soap\Type\CriteriaElement $CriteriaElement
         * @return QueryCriteria
         */
        public function withCriteriaElement($CriteriaElement)
        {
            $new = clone $this;
            $new->CriteriaElement = $CriteriaElement;
    
            return $new;
        }
    }
    
    <?php
    
    namespace App\Soap\Type;
    
    class CriteriaElement
    {
        /**
         * @var string
         */
        private $DataSourceName;
    
        /**
         * @var string
         */
        private $FieldName;
    
        /**
         * @var string
         */
        private $Operator;
    
        /**
         * @var string
         */
        private $Value1;
    
        /**
         * @var string
         */
        private $Value2;
    
        /**
         * @return string
         */
        public function getDataSourceName()
        {
            return $this->DataSourceName;
        }
    
        /**
         * @param string $DataSourceName
         * @return CriteriaElement
         */
        public function withDataSourceName($DataSourceName)
        {
            $new = clone $this;
            $new->DataSourceName = $DataSourceName;
    
            return $new;
        }
    
        /**
         * @return string
         */
        public function getFieldName()
        {
            return $this->FieldName;
        }
    
        /**
         * @param string $FieldName
         * @return CriteriaElement
         */
        public function withFieldName($FieldName)
        {
            $new = clone $this;
            $new->FieldName = $FieldName;
    
            return $new;
        }
    
        /**
         * @return string
         */
        public function getOperator()
        {
            return $this->Operator;
        }
    
        /**
         * @param string $Operator
         * @return CriteriaElement
         */
        public function withOperator($Operator)
        {
            $new = clone $this;
            $new->Operator = $Operator;
    
            return $new;
        }
    
        /**
         * @return string
         */
        public function getValue1()
        {
            return $this->Value1;
        }
    
        /**
         * @param string $Value1
         * @return CriteriaElement
         */
        public function withValue1($Value1)
        {
            $new = clone $this;
            $new->Value1 = $Value1;
    
            return $new;
        }
    
        /**
         * @return string
         */
        public function getValue2()
        {
            return $this->Value2;
        }
    
        /**
         * @param string $Value2
         * @return CriteriaElement
         */
        public function withValue2($Value2)
        {
            $new = clone $this;
            $new->Value2 = $Value2;
    
            return $new;
        }
    }
    

    QueryCriteria class accepts only single CriteriaElement in the provided code. How do I make it accept a list?

    P.S. If I just wrap a list of CriteriaElement[] inside QueryCriteria it results to an error "SOAP-ERROR: Encoding: object has no 'DataSourceName' property".

    Thank you

    opened by danaki 17
  • Ignoring null values when XML is created?

    Ignoring null values when XML is created?

    Hi,

    is it possible to make the generated xml not include any properties that are null? Can I create a TypeConverter to accomplish this?

    Thanks, Hannes

    help wanted new feature 
    opened by HKandulla 16
  • Error wihle creating SoapRequest

    Error wihle creating SoapRequest

    | Q | A |------------ | ----- | Version | 0.7.7

    Hello,

    i'm facing a problem when trying to call my soap service (my webservice is a soap 1.1) when i'm calling \Phpro\SoapClient\Client::call() i got this error: Argument 3 passed to Phpro\SoapClient\Soap\HttpBinding\SoapRequest::__construct() must be of the type string, null given This third argument is $action, but i can't find any way to provide this action

    thanks for your help.

    known-ext-soap-limitation 
    opened by nikophil 15
  • Invalidating permanent location with CachedWsdlProvider

    Invalidating permanent location with CachedWsdlProvider

    Hi,

    CachedWsdlProvider seems rather useful, however we were unable to invalidate the local file to our needs (e.g. when the http cache invalidates in redis), to enforce a fresh load.

    I've created this variant, you may want to consider it here too:

    <?php
    
    declare(strict_types=1);
    
    namespace App\Soap;
    
    use Phpro\SoapClient\Wsdl\Loader\WsdlLoaderInterface;
    use Phpro\SoapClient\Wsdl\Provider\WsdlProviderInterface;
    use Psr\Cache\CacheItemPoolInterface;
    use Symfony\Component\Filesystem\Filesystem;
    
    class CachedWsdlProvider implements WsdlProviderInterface
    {
        protected WsdlLoaderInterface $loader;
        protected CacheItemPoolInterface $wsdlCache;
        protected Filesystem $filesystem;
        protected string $wsdlCacheDir;
        protected array $localCache = [];
    
        public function __construct(
            WsdlLoaderInterface $loader,
            CacheItemPoolInterface $wsdlCache,
            Filesystem $filesystem,
            string $wsdlCacheDir
        ) {
            $this->loader = $loader;
            $this->wsdlCache = $wsdlCache;
            $this->filesystem = $filesystem;
            $this->wsdlCacheDir = $wsdlCacheDir;
        }
    
        public function provide(string $source): string
        {
            if (isset($this->localCache[$source])) {
                return $this->localCache[$source];
            }
    
            $cacheKey = md5($source);
            $cacheFile = $this->wsdlCacheDir.'/'.$cacheKey.'.wsdl';
    
            if (!$this->filesystem->exists($cacheFile) || !$this->wsdlCache->hasItem($cacheKey)) {
                $wsdl = $this->wsdlCache->getItem($cacheKey);
                if (!$wsdl->isHit()) {
                    $wsdl->set($this->loader->load($source));
                    $this->wsdlCache->save($wsdl);
                }
    
                $this->filesystem->dumpFile($cacheFile, $wsdl->get());
            }
    
            return $this->localCache[$source] = $cacheFile;
        }
    }
    

    This could be further enhanced with some sort of debug flag (%kernel.debug% in Symfony) to avoid e.g. the redis check.

    opened by ro0NL 12
  • Error while generating the Types

    Error while generating the Types

    Hi,

    I'm using this library to build a client for an internal service.

    However, I'm having an issue while building the types.

    See here the different relevant config files and log files.

    Soap Client config file: https://del.dog/ifingaivai.txt Log: https://del.dog/mitevaluno.txt Console command: ./vendor/bin/soap-client generate:types -o --config=config/soap-client-Adonis.php -vvv

    I succeeded to find which class is causing the issue and at the end of the processing, I noticed a singularity with the File type, 2 files are generated for it: File.php and File.php.backup

    File.php: https://del.dog/ogruxalofi.txt File.php.backup: https://del.dog/apamaristu.txt

    It looks like the correct file is File.php.backup and that there are some missing stuff in File.php.

    I don't know where to start to debug the issue, any hint/clue is very welcome.

    | Q | A |------------ | ----- | Version | 1.2.0

    opened by drupol 11
  • Feature/make command more flexible

    Feature/make command more flexible

    make the commands GenerateClassmapCommand and GenerateTypesCommand extensible.

    Main purpose of this feature is to setup a custom SoapClient (instead of just new SoapClient()), because we need a custom wsdl handler, since a webservice we are using does not have a valid certificate.

    This is now possible by use the two new functions in the Config class: setGenerateTypesCommandClassName and setGenerateClassmapCommandClassName. Here you can set your own command, which eventually will extends your base commands.

    enhancement 
    opened by cjprinse 11
  • Enummerations, SimpleTypes and Arrays in Entity generation

    Enummerations, SimpleTypes and Arrays in Entity generation

    hi, i played a bit around with the library and noticed that some elements of the wsdl i tested werent recognized in the entity generation:

    1. simpleTypes are ignored <xs:simpleType name="ExampleState">

    2. enumerations are ignored

    <xs:enumeration value="Cancelled">
      <xs:annotation>
        <xs:appinfo>
          <EnumerationValue xmlns="http://schemas.microsoft.com/2003/10/Serialization/">4</EnumerationValue>
        </xs:appinfo>
      </xs:annotation>
    </xs:enumeration>
    
    1. array elements are not converted to arrays minOccurs & maxOccurs could maybe detect arrays.
    <xs:complexType name="PriceArray">
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="unbounded" name="Price" nillable="true" type="tns:Price"/>
      </xs:sequence>
    </xs:complexType>
    

    Maybe i did some misconfiguration or you have some idea to circumvent this?

    question 
    opened by ivoba 11
  • How to throw SoapException for http errors?

    How to throw SoapException for http errors?

    | Q | A |------------ | ----- | Version | 1.7.1

    Support Question

    Instantiating everything using ExtSoapOptions::defaults I assumed SoapFaults would be thrown and caught via a SoapException as described in the docs here.

    In my case, the server was gone and responded with a 403: image image

    I'm probably just using it wrong, but how can I make these cases throw a SoapException?

    opened by tgerakitis 10
  • Client.php may return MixedResponse, but the generated client never expects it, thus causing a PHP error

    Client.php may return MixedResponse, but the generated client never expects it, thus causing a PHP error

    Bug Report

    | Q | A |------------ | ------ | BC Break | no? | Version | 1.1.2

    Summary

    In some cases (I haven't debugged this yet, but invalid response maybe?), Phpro\SoapClient\Client returns a MixedResponse object: https://github.com/phpro/soap-client/blob/390acc42bb70e7d7bf7cc543beb81524fa322ab4/src/Phpro/SoapClient/Client.php#L109-L111

    However, the generated Client class typehints return types of all its methods the respective response class: https://github.com/phpro/soap-client/blob/ca17617f765f0f6cf9fd02b231731d27b16cf0bc/src/Phpro/SoapClient/CodeGenerator/Assembler/ClientMethodAssembler.php#L49-L64

    This causes PHP errors like this: Error: "Return value of App\Client\MyClient::getSomething() must be an instance of App\Client\Type\SomethingResponse, instance of Phpro\SoapClient\Type\MixedResult returned."

    I surely hope that this not the expected behavior? :)

    opened by rimas-kudelis 10
  • Middleware Interface relies upon Http\Client\Common\Plugin

    Middleware Interface relies upon Http\Client\Common\Plugin

    The middleware interface relies upon Http\Client\Common\Plugin which means you effectively have to install httplug even when writing your own handler (that doesnt need httplug)

    Is this intended?

    question 
    opened by tm1000 10
  • Feature: Add FileAssembler

    Feature: Add FileAssembler

    This will add the ability to give your generated files declare(strict_types=1);.

    This depends on a feature in zend-code being merged and tagged. Currently its not possible to generate a file with declare() statements. So the build will probably fail with the tests since the needed method is not there. https://github.com/zendframework/zend-code/pull/169

    I hope I found everything that has to be updated (docs, tests etc). If something is missing or should be changed. Let me know.

    new feature 
    opened by icanhazstring 10
  • How to approach Type AnyXML

    How to approach Type AnyXML

    Hi the generator was able to create GetAllItemsWithStock and GetAllItemsWithStockResponse, response is a AnyXML.

    What would be the best way to parse GetAllItemsWithStockResponse response? I tried many different ways but no luck so far.

    
    <s:element name="GetAllItemsWithStock">
        <s:complexType>
            <s:sequence>
                <s:element minOccurs="0" maxOccurs="1" name="Key" type="s:string"/>
                <s:element minOccurs="0" maxOccurs="1" name="ErrMsg" type="s:string"/>
            </s:sequence>
        </s:complexType>
    </s:element>
    <s:element name="GetAllItemsWithStockResponse">
    <s:complexType>
        <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="GetAllItemsWithStockResult">
                <s:complexType>
                    <s:sequence>
                        <s:any minOccurs="0" maxOccurs="unbounded" namespace="http://www.w3.org/2001/XMLSchema" processContents="lax"/>
                        <s:any minOccurs="1" namespace="urn:schemas-microsoft-com:xml-diffgram-v1" processContents="lax"/>
                    </s:sequence>
                </s:complexType>
            </s:element>
            <s:element minOccurs="0" maxOccurs="1" name="ErrMsg" type="s:string"/>
        </s:sequence>
    </s:complexType>
    </s:element>
    
    

    GetAllItemsWithStockResponse output example:

    <xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
               id="NewDataSet">
        <xs:element msdata:IsDataSet="true" msdata:MainDataTable="Table" msdata:UseCurrentLocale="true" name="NewDataSet">
            <xs:complexType>
                <xs:choice maxOccurs="unbounded" minOccurs="0">
                    <xs:element name="Table">
                        <xs:complexType>
                            <xs:sequence>
                                <xs:element minOccurs="0" name="ItemID" type="xs:int"/>
                                <xs:element minOccurs="0" name="Brand" type="xs:string"/>
                                <xs:element minOccurs="0" name="Department" type="xs:string"/>
                                <xs:element minOccurs="0" name="Group" type="xs:string"/>
                                <xs:element minOccurs="0" name="Name" type="xs:string"/>
                                <xs:element minOccurs="0" name="FullPrice" type="xs:decimal"/>
                                <xs:element minOccurs="0" name="DiscountPrice" type="xs:decimal"/>
                                <xs:element minOccurs="0" name="Size" type="xs:string"/>
                                <xs:element minOccurs="0" name="Quantity" type="xs:int"/>
                                <xs:element minOccurs="0" name="SizeRangeType" type="xs:string"/>
                                <xs:element minOccurs="0" name="Style" type="xs:string"/>
                                <xs:element minOccurs="0" name="GenderID" type="xs:int"/>
                                <xs:element minOccurs="0" name="Gender" type="xs:string"/>
                                <xs:element minOccurs="0" name="SeasonID" type="xs:int"/>
                                <xs:element minOccurs="0" name="Season" type="xs:string"/>
                                <xs:element minOccurs="0" name="Barcode" type="xs:string"/>
                                <xs:element minOccurs="0" name="SKU" type="xs:string"/>
                                <xs:element minOccurs="0" name="StoreBarcode" type="xs:string"/>
                            </xs:sequence>
                        </xs:complexType>
                    </xs:element>
                </xs:choice>
            </xs:complexType>
        </xs:element>
    </xs:schema><diffgr:diffgram xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"
                                 xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <DocumentElement xmlns="">
        <Table diffgr:id="Table1" msdata:rowOrder="0">
            <ItemID>18323365</ItemID>
            <Brand>Acqua di Parma</Brand>
            <Department>N/A</Department>
            <Group>N/A</Group>
            <Name>ff_dev_int_test_21</Name>
            <FullPrice>1.0</FullPrice>
            <DiscountPrice>1.0</DiscountPrice>
            <Size>40</Size>
            <Quantity>50</Quantity>
            <SizeRangeType>CLOTHING WOMEN'S IT</SizeRangeType>
            <Style>skudevinttest21</Style>
            <GenderID>249</GenderID>
            <Gender>WOMEN</Gender>
            <SeasonID>27723467</SeasonID>
            <Season>SS22</Season>
            <Barcode>2018323365193</Barcode>
            <SKU>sku_dev_int_test_21</SKU>
            <StoreBarcode>1832336501</StoreBarcode>
        </Table>
    </DocumentElement>
    
    
    opened by hugomartinsplanet 0
  • Add check for available classes

    Add check for available classes

    There is todo in TypeChecker::isClassType() https://github.com/phpro/soap-client/blob/master/src/Phpro/SoapClient/CodeGenerator/Util/TypeChecker.php#L46-L50 - "add check for available classes".

    The aim of this ticket to implement this check.

    enhancement 
    opened by yenyasinn 5
  • How I do correctly iterate nested child elements?

    How I do correctly iterate nested child elements?

    | Q | A |------------ | ----- | Version | 0.7.11 |

    Support Question

    Be kind, I am pretty new to SOAP, so apologies in advance. We have the following structure in our WSDL: <xsd:choice> <xsd:element name="SupportPerson" type="UserRegistrationDetailsType" minOccurs="0"> <xsd:element name="SupportOrganisation" type="org:SupportOrganisationsType" minOccurs="0"> </xsd:choice>

    I am able to get the class layout sent to the soap library with the expected data structure, however although the <SupportOrganisation> element is generated in the request, it seems to take the shape of some other type - it's like the data is being applied to it differently and so only a small set of fields are going through. This is why I think the <xsd:choice> structure is causing issues here, do we need to iterate over child elements differently? I think the field values in the request are mistakenly applied to the first optional element (in this case the <SupportPerson> element), and so they don't get passed through to the <SupportOrganisation> element and populated.

    known-ext-soap-limitation 
    opened by stgeer 7
  • <xsd:any/> in the WSDL generates a typehint to nonexistent AnyXML class

    in the WSDL generates a typehint to nonexistent AnyXML class

    Bug Report

    | Q | A |------------ | ------ | BC Break | no | Version | 2.2.1

    Summary

    Nonexistent class is sometimes referenced in typehints in the generated code.

    Current behavior

    When the XSD in the WSDL contains references to <xsd:any/>, generated classes will typehint that property as Path\To\Namespace\AnyXML, which is a nonexistant class.

    How to reproduce

    Here's an excerpt from the WSDL which causes this:

          <xsd:element name="GETSKUINFOOutput">
            <xsd:complexType>
                <xsd:sequence>
                  <xsd:element name="RETURN">
                     <xsd:complexType>
                      <xsd:sequence>
                       <xsd:any/>
                      </xsd:sequence>
                     </xsd:complexType>
                    </xsd:element>
                </xsd:sequence>
              </xsd:complexType>
          </xsd:element>
    

    Expected behavior

    I don't know what the expected behavior should be here, but I don't think referencing a nonexistent class can be it. :)

    enhancement help wanted 
    opened by rimas-kudelis 1
  • Support for simple XSD types?

    Support for simple XSD types?

    | Q | A |------------ | ----- | Version | 1.6.0

    Support Question

    Does the generator support xsd simple types?

    I get a lot of typehints like Type\Integer or Type\Boolean -> but no class generated for it.

    Also, some soap functions have native xsd-types as params like xsd:string - but $this->call() requires the second parameter to be of RequestInterface - so you can't pass native php-datatypes.

    WSDL can be found here: https://test.wamtek.eu/test03/services/UMXF0014Port?wsdl

    bug 
    opened by infabo 4
Releases(2.3.0)
Owner
PHPro
PHPro
phpWhois general repository

Introduction This package contains a Whois (RFC954) library for PHP. It allows a PHP program to create a Whois object, and obtain the output of a whoi

PHP Whois 308 Dec 31, 2022
Retrofit implementation in PHP. A REST client for PHP.

Retrofit PHP Retrofit is a type-safe REST client. It is blatantly stolen from square/retrofit and implemented in PHP. ❗ UPGRADE NOTICE ❗ Version 3 int

null 153 Dec 21, 2022
Guzzle, an extensible PHP HTTP client

Guzzle, PHP HTTP client Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and trivial to integrate with web services. Simple interf

Guzzle 22.3k Jan 2, 2023
A Chainable, REST Friendly, PHP HTTP Client. A sane alternative to cURL.

Httpful Httpful is a simple Http Client library for PHP 7.2+. There is an emphasis of readability, simplicity, and flexibility – basically provide the

Nate Good 1.7k Dec 21, 2022
PHP's lightweight HTTP client

Buzz - Scripted HTTP browser Buzz is a lightweight (<1000 lines of code) PHP 7.1 library for issuing HTTP requests. The library includes three clients

Kris Wallsmith 1.9k Jan 4, 2023
HTTPlug, the HTTP client abstraction for PHP

HTTPlug HTTPlug, the HTTP client abstraction for PHP. Intro HTTP client standard built on PSR-7 HTTP messages. The HTTPlug client interface is compati

The PHP HTTP group 2.4k Dec 30, 2022
Unirest in PHP: Simplified, lightweight HTTP client library.

Unirest for PHP Unirest is a set of lightweight HTTP libraries available in multiple languages, built and maintained by Mashape, who also maintain the

Kong 1.3k Dec 28, 2022
↪️ Bypass for PHP creates a custom HTTP Server to return predefined responses to client requests

Bypass for PHP provides a quick way to create a custom HTTP Server to return predefined responses to client requests.Useful for tests with Pest PHP or PHPUnit.

CiaReis 101 Dec 1, 2022
A PHP proxy to solve client browser HTTP CORS(cross-origin) restrictions.

cors-bypass-proxy A PHP proxy to solve client browser HTTP CORS(cross-origin) restrictions. A simple way to solve CORS issue when you have no access t

Gracious Emmanuel 15 Nov 17, 2022
Zenscrape package is a simple PHP HTTP client-provider that makes it easy to parsing site-pages

Zenscrape package is a simple PHP HTTP client-provider that makes it easy to parsing site-pages

Andrei 3 Jan 17, 2022
Async HTTP/1.1+2 client for PHP based on Amp.

This package provides an asynchronous HTTP client for PHP based on Amp. Its API simplifies standards-compliant HTTP resource traversal and RESTful web

AMPHP 641 Dec 19, 2022
Simple HTTP cURL client for PHP 7.1+ based on PSR-18

Simple HTTP cURL client for PHP 7.1+ based on PSR-18 Installation composer require sunrise/http-client-curl QuickStart composer require sunrise/http-f

Sunrise // PHP 15 Sep 5, 2022
Event-driven, streaming HTTP client and server implementation for ReactPHP

HTTP Event-driven, streaming HTTP client and server implementation for ReactPHP. This HTTP library provides re-usable implementations for an HTTP clie

ReactPHP 640 Dec 29, 2022
HTTP header kit for PHP 7.1+ (incl. PHP 8) based on PSR-7

HTTP header kit for PHP 7.1+ (incl. PHP 8) based on PSR-7 Installation composer require sunrise/http-header-kit How to use? HTTP Header Collection Mor

Sunrise // PHP 63 Dec 31, 2022
Express.php is a new HTTP - Server especially made for RESTful APIs written in PHP.

express.php Express.php is a new HTTP - Server especially made for RESTful APIs written in PHP. Features Fast The Library is handles requests fast and

null 5 Aug 19, 2022
PHP Curl ile letgo api kütüphanesi oluşturuldu. php ile letgo giriş yap.

Kendi LETGO API ile işlemler gerçekleştirelim. // email işlemleri $server = 'imap.gmail.com'; $user = '[email protected]'; $pass = 'password'; $port = 9

Görkem Bayraktar 2 Nov 3, 2022
Requests for PHP is a humble HTTP request library. It simplifies how you interact with other sites and takes away all your worries.

Requests for PHP Requests is a HTTP library written in PHP, for human beings. It is roughly based on the API from the excellent Requests Python librar

null 3.5k Dec 31, 2022
Requests for PHP is a humble HTTP request library. It simplifies how you interact with other sites and takes away all your worries.

Requests for PHP Requests is a HTTP library written in PHP, for human beings. It is roughly based on the API from the excellent Requests Python librar

null 3.5k Dec 31, 2022
PHP Curl Class makes it easy to send HTTP requests and integrate with web APIs

PHP Curl Class: HTTP requests made easy PHP Curl Class makes it easy to send HTTP requests and integrate with web APIs. Installation Requirements Quic

null 3.1k Jan 5, 2023