Guzzle: How to cancel url-encode in query?

Created on 27 Feb 2017  路  10Comments  路  Source: guzzle/guzzle

I need to cancel url-encode the "=" character in ClientName=John

API doc:
http://api.wordbee-translator.com:32570/projects?token=xxx&filter=ClientName='John'

The GET Method that I use to implement with filter:

$resp = $project->request('GET', 'projects', [
        'query' => [
            'token' => $tokenId,
            'filter' => 'ClientName=John'
        ]
]);

I get response '400 Bad Request' due to the %3D characters as appears below:
https://api.wordbee-translator.com:32570/projects?token=xxx&filter=ClientName%3DJohn

How to fix it?

kinquestion

Most helpful comment

Intended, but sometimes we are using 3rd party apis which does not do the decode... how to solve the encoding in that case?

All 10 comments

You don't send _John_ as a String to the API:
&filter=ClientName='John' vs 'filter' => 'ClientName=John'. Mind the missing '' around _John_

Thank you for your comment, I still get the same error.
The issue is how to cancel url-encode the "=" character.

For example I tried the following:
'filter=ProjectId' => 77
uri result:
https://api.wordbee-translator.com:32570/projects?token=xxx&filter%3DProjectId=77

And I tried the following:

'filter' => [       
   'ProjectId' => 77    
] 

uri result:
https://api.wordbee-translator.com:32570/projects?token=xxx&filter%5BProjectId%5D=77

How to get the effective uri as follows?
https://api.wordbee-translator.com:32570/projects?token=xxx&filter=ProjectId=77

This is a duplicate of https://github.com/guzzle/guzzle/issues/1696#issuecomment-280092334

Please check the answer there.

One more question.

How can I use this query and cancel urlencode symbols : " (quote) in a request?
['query' => ['Query' => Gtin:"027917022710"]]

Guzzle transformates it to ?Query=Gtin%3A%22648575210037%22

You can't, it's intended. You have to decode it on the receiver side.

Intended, but sometimes we are using 3rd party apis which does not do the decode... how to solve the encoding in that case?

There must be some option to prevent URL encoding of the query string.

The issue I am facing is as follows.

       $paramsJoined = array();

        foreach($api_details['query'] as $param => $value) {
            $paramsJoined[] = "$param=$value";
        }

        $query = implode('&', $paramsJoined);

        $response = $client->get($api_details['url'], [
            'query' => $query,
            'on_stats' => function (TransferStats $stats) use (&$url) {
                $url = $stats->getEffectiveUri();
            }
        ]);
...

'url' => Config::get('apiURL'),
'query' => array(
     'q' => $search_string.' AND prism.creationDate>='.$created_date,
     'maximumRecords' => 100,
      'httpAccept' => 'application/json'
)

...

The actual query that I need

q=keyword AND prism.creationDate>=2017

What Guzzle's effective URI is

q=keyword%2520AND%2520prism.creationDate%253E%3D2017

Expected

q=keyword%20AND%20prism.creationDate%3E%3D2017

What I have tried

Passing the array (instead of joined params).
Appending '?'.$query
Keeping the encoded string -> this results in characters like % getting encoded again.

Any updates about this issue ?

Looks like I can't use Guzzle for Paypal API calls.

https://developer.paypal.com/docs/classic/payflow/integration-guide/#do-not-url-encode-name-value-parameter-data

There should be some option to disable url encoding.

There is a workaround. The Problem is the GuzzleHttp\Psr7\Uri class which apply the encoding to the URI. Since GuzzleHttp\Psr7\Uri implements the Psr7 Interface Psr\Http\Message\UriUriInterface, you can create your own Uri class and pass it to a Guzzle request.

use Psr\Http\Message\UriInterface;

// I didn't test it, it's just to demonstrate how a workaround could look like
MyUrl implements UriInterface
{
    private $parts;

    public function __construct($uri)
    {
        $this->parts = parse_url($uri);
    }

    public function getPath()
    {
        return $this->parts['path'];
    }

    public function getQuery()
    {
        return $this->parts['query'];
    }

    // you have to implement the other functions
}

```php
use MyUrl;
$client->request('GET', new MyUrl('projects'));

Was this page helpful?
0 / 5 - 0 ratings