Galih Abdullah
Galih Abdullah

Reputation: 11

Convert Array php to json

I want to post this array to website using curl, so I must convert it first to json. I used json_encode but I got the wrong format.

   $inv=Array
    ("sales_invoice" => Array
            (
                "transaction_date" => $date,
                "transaction_lines_attributes" => [ Array
                    (
                                "quantity" => 1,
                                "rate" => $price,
                                "discount" => 0,
                                "product_name" => "$ordersku",
                                "tax" => false
                    )],
                "address" => "JL. Gatot Subroto 55, Jakarta, Jawa Barat, 11739",
                "term_name" => "Net 30",
                "deposit_to_name" => "Cash",
                "warehouse_name" => "",
                "due_date" => "$due2",
                "shipping_date" => "$date",
                "shipping_price" => "0.0",
                "shipping_address" => "ship_address",
                "is_shipped" => true,
                "ship_via" => "jne",
                "reference_no" => "$ordernumber",
                "tracking_no" => "",
                "deposit" => "0",
                "person_name" => "Lazada",
                "discount_type_name" => "Value",
                "discount_unit" => 0,
                "custom_id" => "",
                "tax_name" => "Tax 0%",
                "email" => "[email protected]",
                "transaction_no" => "$orderitemid",
            ));

the json format must be like this

{\n  \"sales_invoice\": {\n    \"transaction_date\": \"2015-10-23\",\n    \"transaction_lines_attributes\": [\n      {\n        \"quantity\": 1,\n        \"rate\": 25000000,\n        \"discount\": 0,\n        \"product_name\": \"Sales\",\n        \"tax\": true\n      }\n    ],\n    \"address\": \"JL. Gatot Subroto 55, Jakarta, Jawa Barat, 11739\",\n    \"term_name\": \"Cash_on_Delivery\",\n    \"deposit_to_name\": \"Cash\",\n    \"warehouse_name\": \"New Warehouse\",\n    \"due_date\": \"2015-10-23\",\n    \"shipping_date\": \"2016-09-15\",\n    \"shipping_price\": \"0.0\",\n    \"shipping_address\": \"ship_address\",\n    \"is_shipped\": true,\n    \"ship_via\": \"jne\",\n    \"reference_no\": \"REF1\",\n    \"tracking_no\": \"TR01\",\n    \"deposit\": \"25000000\",\n    \"person_name\": \"Per\",\n    \"discount_type_name\": \"Value\",\n    \"discount_unit\": 30000,\n    \"custom_id\": \"SalesInvoice1\",\n    \"tax_name\": \"PPN Tes\",\n    \"email\": \"[email protected]\",\n    \"transaction_no\": \"4SH4LFS\"\n  }\n}";

Cheers

Upvotes: 1

Views: 68

Answers (1)

Memor-X
Memor-X

Reputation: 2970

90% of this can be done with json_encode and str_replace as i have shown here

$price  = 15.50;
$ordersku   = "TEST_SKU";
$due2   = "due?";
$date   = "2015-10-23";
$ordernumber    = "1900000001";
$orderitemid    = "1500";

$inv=array("sales_invoice" => array
        (
            "transaction_date" => $date,
            "transaction_lines_attributes" => [ array
                (
                            "quantity" => 1,
                            "rate" => $price,
                            "discount" => 0,
                            "product_name" => "$ordersku",
                            "tax" => false
                )],
            "address" => "JL. Gatot Subroto 55, Jakarta, Jawa Barat, 11739",
            "term_name" => "Net 30",
            "deposit_to_name" => "Cash",
            "warehouse_name" => "",
            "due_date" => "$due2",
            "shipping_date" => "$date",
            "shipping_price" => "0.0",
            "shipping_address" => "ship_address",
            "is_shipped" => true,
            "ship_via" => "jne",
            "reference_no" => "$ordernumber",
            "tracking_no" => "",
            "deposit" => "0",
            "person_name" => "Lazada",
            "discount_type_name" => "Value",
            "discount_unit" => 0,
            "custom_id" => "",
            "tax_name" => "Tax 0%",
            "email" => "[email protected]",
            "transaction_no" => "$orderitemid",
        ));

$json = json_encode($inv);

$replacement = array(
    "search" =>  array("{",  "}",  '"', ","),
    "replace" => array('{\n','}\n','\"',',\n')
    );

var_dump(str_replace($replacement["search"],$replacement["replace"],$json));

the result of the str_replace is

{\n\"sales_invoice\":{\n\"transaction_date\":\"2015-10-23\",\n\"transaction_lines_attributes\":[{\n\"quantity\":1,\n\"rate\":15.5,\n\"discount\":0,\n\"product_name\":\"TEST_SKU\",\n\"tax\":false}\n],\n\"address\":\"JL. Gatot Subroto 55,\n Jakarta,\n Jawa Barat,\n 11739\",\n\"term_name\":\"Net 30\",\n\"deposit_to_name\":\"Cash\",\n\"warehouse_name\":\"\",\n\"due_date\":\"due?\",\n\"shipping_date\":\"2015-10-23\",\n\"shipping_price\":\"0.0\",\n\"shipping_address\":\"ship_address\",\n\"is_shipped\":true,\n\"ship_via\":\"jne\",\n\"reference_no\":\"1900000001\",\n\"tracking_no\":\"\",\n\"deposit\":\"0\",\n\"person_name\":\"Lazada\",\n\"discount_type_name\":\"Value\",\n\"discount_unit\":0,\n\"custom_id\":\"\",\n\"tax_name\":\"Tax 0%\",\n\"email\":\"[email protected]\",\n\"transaction_no\":\"1500\"}\n}\n

you simply create your normal json string and then using str_replace add in the \ where you need it. problem is that this method wont insert those spaces/tabs for you.

if you really need those tabs then the best way to do this is with recursion

function altJSonEncode($arr,$tabNo=1)
{
    $returnStr = "";
    $genTabs = "";
    for($i = 0; $i < $tabNo; $i++)
    {
        $genTabs .= "  ";   
    }
    foreach($arr as $key => $val)
    {
        $returnStr .= $genTabs.'\"'.$key.'\": ';
        if(is_array($val))
        {
            $tabNo += 1;
            $returnStr .= altJSonEncode($val,$tabNo);
        }
        else
        {
            $returnStr .= '\"'.$val.'\",\n';
        }
    }
    return '{\n'.$genTabs.$returnStr.$genTabs.'}\n';
}

$price  = 25000000;
$ordersku   = "Sales";
$due2   = "2015-10-23";
$date   = "2015-10-23";
$ordernumber    = "1900000001";
$orderitemid    = "1500";

$inv=array("sales_invoice" => array
        (
            "transaction_date" => $date,
            "transaction_lines_attributes" => [ array
                (
                            "quantity" => 1,
                            "rate" => $price,
                            "discount" => 0,
                            "product_name" => "$ordersku",
                            "tax" => false
                )],
            "address" => "JL. Gatot Subroto 55, Jakarta, Jawa Barat, 11739",
            "term_name" => "Net 30",
            "deposit_to_name" => "Cash",
            "warehouse_name" => "",
            "due_date" => "$due2",
            "shipping_date" => "$date",
            "shipping_price" => "0.0",
            "shipping_address" => "ship_address",
            "is_shipped" => true,
            "ship_via" => "jne",
            "reference_no" => "$ordernumber",
            "tracking_no" => "",
            "deposit" => "0",
            "person_name" => "Lazada",
            "discount_type_name" => "Value",
            "discount_unit" => 0,
            "custom_id" => "",
            "tax_name" => "Tax 0%",
            "email" => "[email protected]",
            "transaction_no" => "$orderitemid",
        ));

var_dump(altJSonEncode($inv));

example

What we are doing here is we pass our array into the function when we first call it but not the second argument (so it has the default value). in our function if we detect the value of the current index in our for each loop is an array and if so we recall out function again sending the array we are up to and also passing in an updated value for $tabNo

this however still isn't perfect because

  • all $keys are outputted, as such because transaction_lines_attributes is an array of arrays the key 0 is outputted for the first and only item
  • in the example link 4 spaces are being outputted (not sure if that's the site's doing but even when i make then match, comparing to the example output the space number doesn't match.
  • everything is treated as a string, as such integers like quantity will have " around the value. also if tax is false an empty string is returned (not sure why it's not a 0 since false = 0 and true = 1 and true still outputs 1, maybe it's just how boolean => string conversion works since an empty string "" is also false in PHP)

but these little problems can be ironed with some more work. however both methods will require their own decode function rather than using json_decode which to me seems more trouble than it's worth if you wanted json in the first place. json_decode works fine with the output of json_encode and vice versa

Upvotes: 1

Related Questions