PHP, Laravel: Eliminate Specific Complex Array from JSON - php

I'm currently developing an API using Laravel for my project, the concept:
Retrieve JSON data from MySQL.
Receive user input from the Front-end (string).
Convert both JSON and string input into an array with similar structure. The array structure here is basically ["ObjectA", "ObjectA_quantity", "ObjectB", "ObjectB_quantity", ...].
Basically, eliminate the quantity of every object of Database's Array, based on every object that User Input's Array got. For example, if the Database's Array got ["pizza", "1", "burger", "2"], and the User Input's Array got ["pizza", "1"], the output of the method is expected to be ["burger", "2"].
The method that I developed will give inconsistent and confusing output, like for some object, it works well, for other it doesn't eliminate anything and if the User Input's Array too big (> 1 object), it also doesn't eliminate anything. I really welcome different approach or anything else that will give the expected output as above. Thank you very much
Here's the source code of the method I've develop: (method's located on: else if ($transactionGetter->type == 'return'), Line 148 and so forth)
https://github.com/andre-nk23/packme-backend/blob/master/app/Http/Controllers/API/TransactionController.php

if it's a JSON you must decode the value before access
$transactionGetter=json_decode($transactionGetter);

Related

Why does Laravel store two different array syntaxes in databases and which one is correct?

I come from a Javascript and Ruby background and this is baffling me. Laravel can store two different array syntaxes in my DB depending on how I handle my array serialization. In my understanding, collect() creates a true Laravel array. Why then is it storing a serialized array? Furthermore, is the {'key':'value'}syntax still an array despite having no square brackets surrounding it? It looks to me like a standard object or a hash, but if I try to do toArray() on it, it recognizes that it's already an array and throws an error. What am I misunderstanding and what is correct here?
Given a form:
edit.blade:
<select class="form-control m-bootstrap-select m_selectpicker" name="temp">
<option value={{ json_encode(array("$key"=>"$cph"), JSON_FORCE_OBJECT) }}>
</select>
The following two controllers syntaxes yield different database insertions.
PageController.php:
$page->cph_default = collect($request->temp);
$page->save();
Laravel stores an array with the following syntax in my database: ["{\"11\":\"1100\"}"]
PageController.php
$page->cph_default = json_decode($request->temp, true);
$page->save();
Laravel stores an array with the following syntax in my database: {"19": "1900"}
A PHP array with the syntax ['key' => 'value'] is called an associative array, and acts like a hash. A JSON-encoded associative array will show up as an object in JSON syntax. Examples and more info on PHP.net
Laravel's collect() function is a convenience wrapper for creating a new Collection. A Collection is not really a "true Laravel array" so much as it is an object wrapper with some convenience methods for modifying the underlying array. Think of it like a scalar object.
In your form when generating the option value, the submitted form value ($request->temp) will be a JSON-encoded string. Literally the string '{"19": "1900"}'.
Calling collect($request->temp) does no modification to that submitted data. It's simply creating a new Collection (array), containing a single string item. If you were to call toArray() on the collection, you'd see something like this:
[
0 => '{"19": "1900"}'
]
Note that this is not an associative array, it is a numeric array with a zero-based index. This array is encoded as a JSON array, not as a hash object. Hence your first result.
Calling json_decode($request->temp) is turning the string back into an associative array (hash) before saving it via Eloquent. Eloquent then calls json_encode() again internally, turning it back into the same JSON as your form's option value.
If you were to decode the form value before creating the collection, the resulting database save would look identical. You'd just have the convenience of the Collection wrapper:
$page->cph_default = collect(json_decode($request->temp, true));
$page->save();
If you're treating the column as a JSON type, you should ensure the data passed to Eloquent is NOT already encoded, or you'll get the double encoding experienced in your first example.
No Matter What is.
First If you are stroring the array into database convert to JSON FORMAT
For eg
$variable = json_encode($request->controlname);
This is the right way to store array
Into database

What is meant by 'a valid array format for collections'?

When calling an REST API method I get back that there is an error
Error processing request stream. The payload must represent a valid array format for collections.
But when searching for:
valid array format for collections
I get back a lot, but nothing clarifies what is meant by this. I'm guessing the data i send is not valid (currently i'm sending an array('foo' => 'Bar')) but this is probably not correct.
Has anybody got a pointer to what is happening here? Or what i could check?
The documentation of ExactOnline (which I'm posting to) is not sufficient. It only states what fields they have, but nothing about these kind of error messages.
==========================
Ok, this needs some clarification, my bad!
As written, i'm communication with ExactOnline, via their API.
I'm calling the method to post a sales order. With that, i'm using a set of scripts Exact provides on their website (for developers).
on page:
https://start.exactonline.nl/docs/HlpRestAPIResourcesDetails.aspx?name=SalesOrderSalesOrders
under 'POST', you can read the mandatory fields, under which 'SalesOrderLines' is one of them. It does not tell me what it expects or in what format.
I wrapped my array in a json_encode and tried again, but no luck. It still tells me the same error.
I'am currently using the same ExactOnline API. Have to say that the documentation lacks in information on this topic indeed!
To make a valid array for collections you have to use the following base:
$array = array(
'InvoiceTo' => 'bc960e43-be9d-409c-9cfe-31ce56cc3238',
'SubscriptionLines' => array(
array('Item' => '7e50702b-5bbf-4b77-ab73-5dad50016e82')
)
)
The json_encode($array) on this list would be:
{
"InvoiceTo":"bc960e43-be9d-409c-9cfe-31ce56cc3238",
"SubscriptionLines":[
{"Item":"7e50702b-5bbf-4b77-ab73-5dad50016e82"}
]
}
So the important part here is to do array(array()) inside the SubScriptionLines. This tells the JSON that you want to use an JSON Array instead of the JSON Object notation.
For your particular question you need to change the keys into the keys given in the documentation for a SalesOrder. Not all manditory fields of the api are included here, because this solution is for Subscriptions. However, the principle will be the same.
Hope this will help you and others implementing the exact API fully :)
How are you serializing your payload? If it is meant to be in JSON format, a collection would look like this:
[
{
"foo": "bar"
},
{
"foo": "baz"
}
]

PHP json_encode multiple arrays into one object

I am trying to return multiple arrays in one JSON object and having some difficulty with the syntax. An Android app receives updates from multiple tables, that I wish to be returned in one response.
Currently, this is how I am encoding the various result sets:
$json=json_encode(array($table1, $table2, $table3, $table4, $table5, $table6));
The data is returned in this format:
[{"table1":[{...}]},{"table2":[{...}]},...]
In the Android code, I'd like to be able to parse it as a JSONObject, from which I can then retrieve each array by name instead of parsing it as a JSONArray and retrieving each sub array by position. The JSON response would look like this instead:
{{"table1":[{...}]},{"table2":[{...}]},...}
It seems all I need to do is wrap the results arrays in an object, instead of an array on the PHP side, but although I've managed to blindly cobble together enough PHP code to get this far, I can't seem to figure out that final step.
Your last example is not valid JSON, curly braces always mean object with keys; instead you're treating it as an array. If you want an object, then add keys to the array in PHP like so:
$json=json_encode(array('a' => $table1, 'b' => $table2, 'c' => $table3));
This would then yield
{"a":{"table1":[{...}]},"b":{"table2":[{...}]},...}
Which seems to be what you want.
#Anonymous answer did the trick. Just to clarify, I had to clean up what I was doing previously, so instead of this:
$table1['table1'] =$stmt_table1->fetchAll(PDO::FETCH_ASSOC);
$table2['table2'] =$stmt_table2->fetchAll(PDO::FETCH_ASSOC);
...
$json=json_encode(array($table1, $table2, $table3, $table4, $table5, $table6));
I now have this:
$table1_results =$stmt_table1->fetchAll(PDO::FETCH_ASSOC);
$table2_results =$stmt_table2->fetchAll(PDO::FETCH_ASSOC);
...
$json=json_encode(array('table1' => $table1_results , 'table2' => $table2_results,...);

How to return an array instead of object in JSON response?

I've one working REST API developed using Slim PHP framework.
It's working absolutely fine.
The only issue is when there is no error present i.e. an array $errors is empty it comes as an array in JSON response but when the array $errors contains any error like $errors['user_name'] then it comes as an object in JSON response.
Actually I want to return the array when error is present. How should I do this? Can someone please help me in this regard?
Thanks in advance.
When your $errors is not empty, pass it through json_encode and echo it.
It will give you JSON object in return,
then convert JSON object into JavaScript array. (see the following code.)
var o = {"0":"1","1":"2","2":"3","3":"4"}; // your response object here
var arr = Object.keys(o).map(function(k) { return o[k] });
console.log(arr);
Recently got a close issue with Symfony's JsonResponse::create()
Turns out arrays with index not starting at 0 will be encoded into objects, as well as arrays with "holes", and probably any array with at least one non-int key.
In other word, arrays with anything else than consecutive numeric keys starting from index 0 seem to be encoded as object.
I guess this is designed to avoid sending big empty arrays when you map a handful of datas with big indices like [14334, 839493, 246193], and is probably documented somewhere.
Learning if this is a Symfony of json_encode behavior from comments would be welcomed addition :)
Note : Even if you return an array, it seems necessary to wrap it in an object for GET request to prevent some XSSI and JSON-JavaScript Hijacking.

PHP multidimensional array to JSON

So im trying to figure out the best way to get MySql table data into either a multidimensional PHP array or convert that multidimensional array into a json string.
Essentially what im trying to do is have a php include that returns the JSON string so i can iterate through it. I am needing a single key with multiple values, so im not 100% sure that im headed in the right direction.
I want to assign multiple values to the same key, for example:
[{"key1": "package1", "package2", "package3"}, {"key2": "package1", "package2", "package3", "package4"}]
I think that is not going to work right? Because i dont have any type of index's?
That is not valid JSON. The structure you are looking for would be something like:
[
{"key1": ["package1", "package2", "package3"]},
{"key2": ["package1", "package2", "package3", "package4"}]
^ An array as the value to the key "key1", "key2", etc..
]
At the PHP side, you would need something like:
For every row fetched from MySQL
$arr[$key] = <new array>
for each package:
append package to $arr[$key]
echo out json_encode($arr)
JS arrays have an implicit array keying, starting at index 0. What you've got is a perfectly valid JS array, the equivalent of having written:
var x = []; // create new empty array
x[0] = {"key1": .... }; // first object
x[1] = {"key2": ....} // second object
Note that the contents of your {} sub-objects is NOT valid.
You should never EVER built a JSON string by hand. It's too unreliable and easy to mess up. It's just easier to use a native data structure (php arrays/objects), then json_encode() them. Ditto on the other end of the process - don't decode the string manually. Convert to a native data structure (e.g. json_decode(), JSON.parse()) and then deal with the native structure directly.
essentially, JSON is a transmission format, not a manipulation format.

Categories