0

I'm working on a logging tool for our software and I have ran into an issue with json_decode returning null and I was hoping to get some help.

The json object looks like this:

{
    'id': 'string',
    'request': {
        'headers': {
            ...
        },
        'body': 'jsonstring'
    },
    'response' {
        ...
    },
}

The problem is with the request->body part. Since its a a json object but saved as a string with quotations arround it, it seems to mess with the json_decode function and it returns null.

Editing the log entry to remove the quotation marks arround the body jsonstring in the request makes it go through, but this is how it is logged, and I'm not looking forward to potentialy having to rewrite the logging code. So any help is much welcome at this point.

Edit for the real JsonString being used. Removed auth and URLs however.

{
    "payment_id": "1",
    "type": "post",
    "title": "Create Order",
    "request": {
        "headers": {
            "Content-type": "application/json",
            "Accept": "application/json",
            "Authorization": "string"
        },
        "method": "POST",
        "body": "{
            "order": {
                "items": [{
                    "reference": "8",
                    "name": "Test Product",
                    "quantity": 2,
                    "unit": "pcs",
                    "unitPrice": 12500,
                    "taxRate": 2500,
                    "taxAmount": 5000,
                    "grossTotalAmount": 25000,
                    "netTotalAmount": 20000
                }, {
                    "reference": "test",
                    "name": "Test",
                    "quantity": 1,
                    "unit": "pcs",
                    "unitPrice": 20000,
                    "taxRate": 2500,
                    "taxAmount": 5000,
                    "grossTotalAmount": 25000,
                    "netTotalAmount": 15000
                }, {
                    "reference": "1",
                    "name": "Flat rate",
                    "quantity": 1,
                    "unit": "pcs",
                    "unitPrice": 6125,
                    "taxRate": 2500,
                    "taxAmount": 1225,
                    "grossTotalAmount": 6125,
                    "netTotalAmount": 4900
                }],
                "amount": 56125,
                "currency": "SEK",
                "shipping": {
                    "costSpecified": true
                }
            },
            "checkout": {
                "url": "",
                "termsUrl": "",
                "shipping": {
                    "countries": [],
                    "merchantHandlesShippingCost": true
                },
                "consumerType": {
                    "supportedTypes": ["B2C"]
                }
            },
            "notifications": {
                "webHooks": [{
                    "eventName": "payment.reservation.created",
                    "url": "",
                    "authorization": ""
                }]
            }
        }"
    },
    "response": {
        "headers": {},
        "body": {
            "errors": {
                "notifications.WebHooks[0].Url": ["Field is not accepted as a valid URL"]
            }
        },
        "response": {
            "code": 400,
            "message": "Bad Request"
        },
        "cookies": [{
            "name": "visid_incap_1152497",
            "value": "2qY5gE/QT6W4CmOH1cLUuig yFsAAAAAQUIPAAAAAABsjnmr3oFW5wXzhutW3EWq",
            "expires": 1571353603,
            "path": "/",
            "domain": "api.dibspayment.eu"
        }, {
            "name": "incap_ses_273_1152497",
            "value": "hXtkOPG/TwEHQCnMhuTJAyg yFsAAAAALrqG9pupkT/7iEMdOohRTw==",
            "expires": null,
            "path": "/",
            "domain": "api.dibspayment.eu"
        }],
        "filename": null,
        "http_response": {
            "data": null,
            "headers": null,
            "status": null
        }
    }
}
  • That is NOT a valid JSON String! JSON insists on double quotes for a start – RiggsFolly Oct 18 '18 at 08:53
  • So once you json_decode the outer JSON String you then have to json_decode the inner piece of JSON as a seperate process – RiggsFolly Oct 18 '18 at 08:54
  • use jsonlint.com or something similar to check syntax, post above is corrent that's invalid json – Mason Stedman Oct 18 '18 at 08:55
  • That is true, my apologies. I'm just more used to writing with single quotes and used that while wiring the post. And also this is also a truncated version of the json string, since the real one is very long and most of the data is not needed for this issue. But do you have any ideas on how to solve the issue i asked about? – user10522889 Oct 18 '18 at 08:56
  • @RiggsFolly But running any json_decode on the outer string results in a null return unless i remove the comments arround the inner. How would i just run it on the outer? – user10522889 Oct 18 '18 at 08:57
  • Can you give a real example? I doubt that the inner json is not properly escaped on quotes which cause the json_decode failed. – iamnoten Oct 18 '18 at 09:01
  • @iamnoten I edited the above post with the real jsonstring. – user10522889 Oct 18 '18 at 09:08
  • Well as I assume you are writing the logging, fix it to create valid JSON – RiggsFolly Oct 18 '18 at 09:16
  • You might wann have a look at this :- https://stackoverflow.com/questions/8815586/convert-invalid-json-into-valid-json – Anjana Silva Oct 18 '18 at 10:05

1 Answers1

-1

Use jsonlint.com or something similar to check syntax, if json_decode returns null it's because whatever you fed it wasn't valid json. Protip, parse your data as a normal php array and just json_encode it at the end. If you have incoming json data use

json_decode($json, true);

to have it process as an array vs an object. It's a lot easier to just work with arrays and enocde them after the fact.

Edit:

"body": "{

is your problem upon seeing the full string, you're adding a " before the body object in the request. Parse it in a linter, it's an invalid json object (and thanks to whoever downvoted this answer, go lint it yourself :P)

Mason Stedman
  • 613
  • 5
  • 12
  • Thank you for your reply. We are using a normal PHP array for as long as possible. The function used for the request uses a PHP array for the request, however the body to be sent to the API for this needs to be a json string. Which is why in the PHP array we set the body similarly to this: $request['body]] = json_encode( $request_body ); Sadly without rewriting some parts of the code, this is the format that its logged as. But if there is no way arround it, then a rewrite is needed it seems like. – user10522889 Oct 18 '18 at 09:11
  • If you interact w\ everything as an array, doing: echo json_encode($array); should parse it into a proper json object..., edit above – Mason Stedman Oct 18 '18 at 09:14
  • Yes, i know that is the issue, as i mentioned in my first post. But is there any way arround this that you know off? Without a big rewrite of the code that is :) – user10522889 Oct 18 '18 at 09:21
  • What are you using to create the request object? It looks like it doesn't want a string for the request body, but rather an actual object. – Mason Stedman Oct 18 '18 at 09:27
  • Im using a function that returns a PHP array with a header, method and body. The body is simply set as 'body' => json_encode( $this->request_body() ), and request_body() returns a PHP array. I dont manually add any quotes. – user10522889 Oct 18 '18 at 09:29
  • That's my point, you're encoding the json (which turns it into a string) which some things don't want (they're looking for an object for their POST params). That's why I was wondering what you're using to send the request. – Mason Stedman Oct 18 '18 at 09:29
  • Since this is for a woocommerce/wordpress plugin im using their function for making a HTTP request. https://developer.wordpress.org/reference/classes/WP_Http/request/ Passing it as an array instead causes a error from the API, it needs to be sent over as a jsonstring. – user10522889 Oct 18 '18 at 09:35
  • I get what they want, and what you're trying to do but can you post the code you're using to parse your request? Your cURL or w\e medium the request is generated in is malformed and without seeing what your actually using to create request it's hard to debug why it's doing what it's doing. It's taking your string and adding a random object closing tag at the end, which makes me think it's expecting input in a different format. – Mason Stedman Oct 18 '18 at 09:46
  • Yes my code works to send the request. This is how we do it for all our requests. I want to stress however, we just json_encode the request args for the log, not for the actual request. This is because we wanted the logs to be ledgible to some degree. And now im trying to build a tool that builds on that and parses the json from a text file. However, if that does not work, im going to go for a serialized log file instead and read from that which should work better. – user10522889 Oct 18 '18 at 09:49
  • I'm saying we all see what the problem is (sorry for the pre-emptive answer). Without seeing what's constructing the request, it's impossible to pin down what format the request needs to be in. Are you using cURL? a framework? something proprietary? You've got a valid json string re: what you encoded, but w\e you're using to send the request doesn't seem to want that as input – Mason Stedman Oct 18 '18 at 09:55