I'm need to execute a REST API POST request with PHP.
The URL post parameters looks like this and works fine when executed as such:
https://example.com.json?userid=MYUSER&key=MYKEY&order=000000&server=ns1.example.com&server=ns2.example.net&server=ns3.example.net
I use the following PHP array with success before without any issues for passing unique values to the same API in my PHP Curl Request:
$data = array(
'userid' => 'value',
'key' => 'value',
'order' => 'value',
);
The problem now, looking at the URL is that the "server" parameters accepts more than one value (order is not important) and I'm supposed to pass this as an string of arrays, minimum of 2 values.
But this does not work:
$data = array(
'userid' => 'value',
'key' => 'value',
'order' => 'value',
'server' => array('ns1.example.net','ns2.example.net')
);
I tried multiple different ways. How do I pass multiple values to the same parameter on that array?
Related
I'm trying to use the Firebase PHP API to update/append a document field's array with a map
I have the following code in Python that works fine
ref = db.collection(u'jobs').document(jobId)
ref.update({
u'messages': firestore.ArrayUnion([{
u'category': u'0',
u'message': u'TEST',
u'sender': u'TEAM',
}])
})
Though when I try to replicate it in PHP, it doesn't work. I tried a lot of different ways to view the errors, but all I get is 500 INTERNAL SERVER ERROR.
require 'vendor/autoload.php';
use Google\Cloud\Firestore\FirestoreClient;
use Google\Cloud\Firestore\FieldValue;
$firestore = new FirestoreClient([
'projectId' => 'XXX-XX',
'credentials' => 'key.json'
]);
$jobId = "XXXX";
$docRef = $firestore->collection('jobs')->document($jobId);
$docRef->update([
'messages' => FieldValue::arrayUnion([{
'category' : '0',
'message' : 'TEST',
'sender' : 'TEAM',
}])
]);
I looked up samples of Array Union in PHP, adding data with PHP. I've tried a lots of variations of : or => or arrayUnion([]) or arrayUnion({[]}) to no avail.
Any idea what is causing this?
Looks like there's a few things going wrong here.
First, PHP uses arrays for both maps and "normal" arrays. There is no object literal ({}) in PHP. Array values are specified using the => operator, not :.
Second, DocumentReference::update() accepts a list of values you wish to change, with the path and value. So an update call would look like this:
$docRef->update([
['path' => 'foo', 'value' => 'bar']
]);
You can use DocumentReference::set() for the behavior you desire. set() will create a document if it does not exist, where update() will raise an error if the document does not exist. set() will also replace all the existing fields in the document unless you specify merge behavior:
$docRef->set([
'foo' => 'bar'
], ['merge' => true]);
Therefore, your code can be re-written as either of the following:
$jobId = "XXXX";
$docRef = $firestore->collection('jobs')->document($jobId);
$docRef->set([
'messages' => FieldValue::arrayUnion([[
'category' => '0',
'message' => 'TEST',
'sender' => 'TEAM',
]])
], ['merge' => true]);
$jobId = "XXXX";
$docRef = $firestore->collection('jobs')->document($jobId);
$docRef->update([
[
'path' => 'messages', 'value' => FieldValue::arrayUnion([[
'category' => '0',
'message' => 'TEST',
'sender' => 'TEAM',
]])
]
]);
One final thing to note: arrayUnion will not append duplicate values. So if the value you provide (including all keys and values in the nested map) already exists, it will not be appended to the document.
If you haven't already, turn up error reporting in your development environment to receive information about why your code is failing. PHP will inform you about the parse errors your snippet included, and the Firestore client will give you errors which can often be quite useful.
From Firebase Documentation:
$cityRef = $db->collection('cities')->document('DC');
// Atomically add a new region to the "regions" array field.
$cityRef->update([
['path' => 'regions', 'value' => FieldValue::arrayUnion(['greater_virginia'])]
]);
I would assume you would like something like this:
$docRef = $firestore->collection('jobs')->document($jobId);
// Atomically add new values to the "messages" array field.
$docRef->update([
['path' => 'messages', 'value' => FieldValue::arrayUnion([[
'category' : '0',
'message' : 'TEST',
'sender' : 'TEAM',
]])]
]);
I'm using an api that has a "range" parameter that can apply to several different parameter items. The range i'm focusing on is "price". I'm using guzzle in laravel and according to the api documentation, the query for this particular parameter should be written like this "&range_facet=price|500|2500|250"...this is broken down into the minimum, maximum, and interval values of the price range parameter. That's not necessarily important to this question. When i try and run this query as is, i get nothing returned. When I remove that particular parameter, i get values but obviously they're not filtered the way i want them to be. When i run this in Insomnia, the pipes are replaced by "%7C", which is obviously (obviously?) not interpreted by the api as it's not how it's waiting for the GET request to be made. How can I insert the pipes into the query so that it calls the correct way?
I've tried to create an additional nested array with the price value being broken up into key value pairs but that didn't work either.
'range_facets' => ['price'['start'=>'500', end=>'2500', 'interval'=>'250']],
$client = new Client();
$result = $client->request('GET', "http://api.example.com", [
'headers' => [
'Host' => 'example-host',
'Content-Type' => 'application/json'
],
'query' => [
'api_key' => 'my_api_key',
'range_facets' => 'price|500|2500|250',
'year' => $year,
'latitude' => '30.170222',
'longitude' => '92.01320199',
'radius' => 500,
'start' => 0,
'rows' => 50
]
]);
I'd like to filter my prices but I need the pipe to be able to do it.
This is exactly how it should be. %7C should be decoded on the server side to | automatically (about query string encoding).
I bet the issue is in different place.
I'm calling an API using php and SOAP.
some parts of the request are like:
<fin:Customer>
<fin1:Address>
<fin1:City>City</fin1:City>
<fin1:Country>CA</fin1:Country>
</fin1:Address>
<fin:Customer>
Which is easy to do with arrays:
'Customer' => array(
'Address' => array (
'City' => $City,
'Country' => $Country,
),
But my challenge is for this part:
<fin:Criterions>
<fin:Criterion name="VALX">17</fin:Criterion>
<fin:Criterion name="VALOP">1</fin:Criterion>
<fin:Criterion name="VALLP">10</fin:Criterion>
<fin:Criterion name="TMS">3</fin:Criterion>
Because all tags have the same name, and they also have a name parameter and a value.
How can I pass that to SOAP API?
Is it possible to use arrays?
Thanks in advance!
The easiest way to construct a request, send it and handle the response is to use a WSDL to PHP generator as it'll normally generate each class for every parameter you need to send (in addition to the response objects and the operations classes)
Knowing this, you'll be able to easily see how to pass these "duplicated" tags as it is certainly an array of object that you must pass,
Try the PackageGenerator project which should work fine,
Solution:
'Criterions' => array(
'Criterion' => array(
array('name'=> 'VALX' , '_'=> '17' ),
array('name'=> 'VALOP' , '_'=> '1' ),
array('name'=> 'VALLP' , '_'=> '10' ),
array('name'=> 'TMS' , '_'=> '3' )
));
Be sure to use underscore ('_'), if other values (e.g. val, value, etc) didn't work.
Might save someone's time and effort.
I have built an API that I want to test. By that reason I'm building a simple client to try out the different features (CRUD). Below is the function for updating a producer, which works fine. However, I also want to be able to update parts of a producer, e.g. address (/producers/8?method=put&address=milkyway).
The array producer always contains the same elements (name, address, zipcode etc) but I only want to update the producer with the elements in the array which contains of anything. What I mean with that is that if for example the name element in the array is empty then name shouldn't be included in *http_build_query*. If only the name element contains of anything then only name should be updated.
So, let's say that the array (except for id that of course is mandatory) contains of address. How can I dynamically add only that to *http_build_query* ?
Thanks in advance!
public function UpdateProducer($producer) {
$url = 'http://localhost/webbteknik2/Labb2/api/v1/producers/ . $producer['id'] . '?method=put';
$data = http_build_query(array(
'name' => $producer['name'],
'address' => $producer['address'],
'zipcode' => $producer['zipcode'],
'town' => $producer['town'],
'url' => $producer['url'],
'imgurl' => $producer['imgurl'],
'latitude' => $producer['latitude'],
'longitude' => $producer['longitude'],
));
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
...
the rest of the curl code
}
Note: I know this is bad coding in many ways, but as I said I only, asap want to be able to test the CRUD functionality through the client.
use array_filter to remove the empty elements....
$params = array(
'name' => $producer['name'],
'address' => $producer['address'],
'zipcode' => $producer['zipcode'],
'town' => $producer['town'],
'url' => $producer['url'],
'imgurl' => $producer['imgurl'],
'latitude' => $producer['latitude'],
'longitude' => $producer['longitude'],
);
$data = http_build_query(array_filter($params, 'is_null'));
How can you specify a max result set for Magento SOAP queries?
I am querying Magento via SOAP API for a list of orders matching a given status. We have some remote hosts who are taking too long to return the list so I'd like to limit the result set however I don't see a parameter for this.
$orderListRaw = $proxy -> call ( $sessionId, 'sales_order.list', array ( array ( 'status' => array ( 'in' => $orderstatusarray ) ) ) );
I was able to see that we do get data back (6 minutes later) and have been able to deal with timeouts, etc. but would prefer to just force a max result set.
It doesn't seem like it can be done using limit, (plus you would have to do some complex pagination logic to get all records, because you would need know the total number of records and the api does not have a method for that) See api call list # http://www.magentocommerce.com/api/soap/sales/salesOrder/sales_order.list.html
But what you could do as a work around is use complex filters, to limit the result set base on creation date. (adjust to ever hour, day or week base on order volume).
Also, since you are using status type (assuming that you are excluding more that just cancel order), you may want to think about getting all order and keep track of the order_id/status locally (only process the ones with the above status) and the remainder that wasn't proceed would be a list of order id that may need your attention later on
Pseudo Code Example
$params = array(array(
'filter' => array(
array(
'key' => 'status',
'value' => array(
'key' => 'in',
'value' => $orderstatusarray,
),
),
),
'complex_filter' => array(
array(
'key' => 'created_at',
'value' => array(
'key' => 'gteq',
'value' => '2012-11-25 12:00:00'
),
),
array(
'key' => 'created_at',
'value' => array(
'key' => 'lteq',
'value' => '2012-11-26 11:59:59'
),
),
)
));
$orderListRaw = $proxy -> call ( $sessionId, 'sales_order.list', $params);
Read more about filtering # http://www.magentocommerce.com/knowledge-base/entry/magento-for-dev-part-8-varien-data-collections