I am new to API integration and PHP. I recently integrated a VIN decoder into my app. Enter a vehicle's VIN into the input box, select submit, and all information regarding that vehicle from the API's database is presented.
The data is stored as an associative array, with categories and their corresponding elements. For example for VIN: WAUBFAFL6FA058452 one of the categories is Make and its element is Audi.
Some VIN's carry more data with them than others. I only wanted the categories with data to show up upon selecting submit. So with some help, I added this line of code:
foreach ($json['Results'][0] as $k => $v){
if (!empty($v)) {
$results .= ($k).": ".($v).'<br />';
}
}
My next hurdle is taking the output, the categories and their elements, and organizing/formatting them while keeping the logic I defined above. I only want the categories with data to show up.
I am not sure how to target single categories to format them. Currently, the output is presented in alphabetical order. I want to define my own output layout.
Current Output:
AirBagLocCurtain: All Rows
AirBagLocFront: 1st Row (Driver & Passenger)
AirBagLocSide: 1st Row (Driver & Passenger)
BodyClass: Sedan/Saloon
DisplacementCC: 1984
DisplacementCI: 121.071108283
DisplacementL: 1.984000
And so on....
How can I change this layout? I am looking to change the output layout to something like the following.
Desired Output:
VIN: WAUBFAFL6FA058452
General –
Make: AUDI
ModelYear: 2015
Model: A4
BodyClass: Sedan/Saloon
Doors: 4
Series: Premium quattro
VehicleType: PASSENGER CAR
Safety -
AirBagLocCurtain: All Rows
AirBagLocFront: 1st Row (Driver & Passenger)
AirBagLocSide: 1st Row (Driver & Passenger)
SeatBeltsAll: Manual
Engine -
DisplacementCC: 1984
DisplacementCI: 121.071108283
DisplacementL: 1.984000
EngineCylinders: 4
EngineHP: 220
EngineKW: 164.0540
EngineManufacturer: Audi
EngineModel: Flex Fuel Capable engine
TransmissionStyle: Automatic
OtherEngineInfo: Fuel: Gas (50-St); Federal / California Emission Standard: BIN 5 / ULEV II; Emissions Certification Test Group: FVGAV02.0AUB / FVGAJ02.0AUF E85
FuelTypePrimary: Gasoline
FuelTypeSecondary: Ethanol (E85)
Factory -
Manufacturer: AUDI
ManufacturerId: 1149
PlantCity: Ingolstadt
PlantCountry: Germany
Other -
ErrorCode: 0 - VIN decoded clean. Check Digit (9th position) is correct
TPMS: Indirect
Here is my html code, just the input bar and submit button:
<!DOCTYPE html>
<html>
<head>
<title>VIN Decoder API Test</title>
<style type="text/css">
input,button {width: 200px;display: block;margin-left: auto;margin-right: auto;}
button {width: 100px;background-color: darkgray;}
</style>
</head>
<body>
<form action="processvin3.php" method="post">
<input type="text" id="b12" placeholder="Enter VIN" name="b12" maxlength="100"/>
<br>
<button id="submit_btn">Submit</button>
</form>
<br>
<br>
</body>
</html>
And my php code:
<?php
$vin = $_POST["b12"];
if ($vin) {
$postdata = http_build_query([
'format' => 'json',
'data' => $vin
]
);
$opts = [
'http' => [
'method' => 'POST',
'content' => $postdata
]
];
$apiURL = "https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVINValuesBatch/";
$context = stream_context_create($opts);
$fp = fopen($apiURL, 'rb', false, $context);
$line_of_text = fgets($fp);
$json = json_decode($line_of_text, true);
fclose($fp);
foreach ($json['Results'][0] as $k => $v){
if (!empty($v)) {
$results .= ($k).": ".($v).'<br />';
}
}
echo $results;
}
else {
echo 'No Vin Inputted';
}
?>
Any suggestions, tips, or answers are greatly appreciated. Thanks so much.
I recommend a "master" array to filter and prepare your categorically grouped data. See inline comments for more explanation:
Code: (Demo)
Your Master Array:
$master = [
"General" => [
"Make" => "",
"ModelYear" => "",
"Model" => "",
"BodyClass" => "",
"Doors" => "",
"Series" => "",
"VehicleType" => ""
],
"Safety" => [
"AirBagLocCurtain" => "",
"AirBagLocFront" => "",
"AirBagLocSide" => "",
"SeatBeltsAll" => ""
],
"Engine" => [
"DisplacementCC" => "",
"DisplacementCI" => "",
"DisplacementL" => "",
"EngineCylinders" => "",
"EngineHP" => "",
"EngineKW" => "",
"EngineManufacturer" => "",
"EngineModel" => "",
"TransmissionStyle" => "",
"OtherEngineInfo" => "",
"FuelTypePrimary" => "",
"FuelTypeSecondary" => ""
],
"Factory" => [
"Manufacturer" => "",
"ManufacturerId" => "",
"PlantCity" => "",
"PlantCountry" => ""
],
"Other" => [
"ErrorCode" => "",
"TPMS" => ""
]
];
Processing:
foreach ($master as $category => &$items) { // allow modification of $master data with &
foreach ($items as $k => &$v) { // allow modification of $master data with &
if (isset($json['Results'][0][$k]) && strlen($json['Results'][0][$k])) { // only bother to process/display desired keys and non-empty values
$new = $json['Results'][0][$k];
if ($k == "DisplacementCC") {
$v = "Engine Displacement 2: $new cc's";
} elseif ($k == "DisplacementCI") {
$v = "Engine Displacement 3: $new ci's";
} elseif ($k == "DisplacementL") {
$v = "Engine Displacement 1: " . round($new, 1) . " liters";
} elseif ($k == "EngineKW") {
$v = "Kilowatts: $new kw";
} elseif ($k == "EngineManufacturer") {
$v = "Engine Manufacturer: $new";
} elseif ($k == "EngineModel") {
$v = "Engine Model: $new";
} elseif ($k == "FuelTypePrimary") {
$v = "Primary Fuel Type: $new";
} elseif ($k == "FuelTypeSecondary") {
$v = "Secondary Fuel Type: $new";
} elseif ($k == "EngineHP") {
$v = "Horsepower: $new hp";
} elseif ($k == "EngineCylinders") {
$v = "Engine Size: $new cylinders";
} else {
$v = "$k: $new";
}
} else {
unset($master[$category][$k]); // remove unwanted element from master
}
}
}
unset($items, $v); // just as a precaution to eliminate the referenced variables
echo "<div id=\"VIN\">{$json['Results'][0]['VIN']}</div>\n\n";
// now iterate the updated $master multi-dimensional array and only display the "good stuff"
foreach ($master as $category => $items) {
if (!empty($items)) { // only display categories & rows of data when the category holds 1 or more values
echo "<div class=\"group\">$category -</ br>";
foreach ($items as $v) {
echo "<div class=\"row\">$v</div>";
}
echo "</div>";
}
}
Output:
<div id="VIN">WAUBFAFL6FA058452</div>
<div class="group">General -</ br>
<div class="row">Make: AUDI</div>
<div class="row">ModelYear: 2015</div>
<div class="row">Model: A4</div>
<div class="row">BodyClass: Sedan/Saloon</div>
<div class="row">Doors: 4</div>
<div class="row">Series: Premium quattro</div>
<div class="row">VehicleType: PASSENGER CAR</div>
</div>
<div class="group">Safety -</ br>
<div class="row">AirBagLocCurtain: All Rows</div>
<div class="row">AirBagLocFront: 1st Row (Driver & Passenger)</div>
<div class="row">AirBagLocSide: 1st Row (Driver & Passenger)</div>
<div class="row">SeatBeltsAll: Manual</div>
</div>
<div class="group">Engine -</ br>
<div class="row">Engine Displacement 2: 1984 cc's</div>
<div class="row">Engine Displacement 3: 121.071108283 ci's</div>
<div class="row">Engine Displacement 1: 2 liters</div>
<div class="row">Engine Size: 4 cylinders</div>
<div class="row">Horsepower: 220 hp</div>
<div class="row">Kilowatts: 164.0540 kw</div>
<div class="row">Engine Manufacturer: Audi</div>
<div class="row">Engine Model: Flex Fuel Capable engine</div>
<div class="row">TransmissionStyle: Automatic</div>
<div class="row">OtherEngineInfo: Fuel: Gas (50-St); Federal / California Emission Standard: BIN 5 / ULEV II; Emissions Certification Test Group: FVGAV02.0AUB / FVGAJ02.0AUF E85</div>
<div class="row">Primary Fuel Type: Gasoline</div>
<div class="row">Secondary Fuel Type: Ethanol (E85)</div>
</div>
<div class="group">Factory -</ br>
<div class="row">Manufacturer: AUDI</div>
<div class="row">ManufacturerId: 1149</div>
<div class="row">PlantCity: Ingolstadt</div>
<div class="row">PlantCountry: Germany</div>
</div>
<div class="group">Other -</ br>
<div class="row">ErrorCode: 0 - VIN decoded clean. Check Digit (9th position) is correct</div>
<div class="row">TPMS: Indirect</div>
</div>
*note, you can use !empty()
rather than isset()
then strlen()
ONLY if you KNOW that you will never have 0
as a valid value. empty()
will mistake 0
as a "falsy"/"empty" value and silently call for the element's removal from the master array.
You made a good start with
foreach ($json['Results'][0] as $k => $v){
if (!empty($v)) {
$results .= ($k).": ".($v).'<br />';
}
}
but before your start printing output try creating a your own array for example
$data = array();
foreach ($json['Results'][0] as $k => $v){
if (!empty($v)) {
$data[$k] = $v;
}
}
Then you could take your time and echo the list you want.
With this simple method, hopefully the fields you want in your list being excluded by the blank check are very low. Then you would have to do something about that.
echo 'Make: '. $data['Make'] . '<br>';
echo 'ModelYear: '. $data['ModelYear']. '<br>';
echo 'Model: '. $data['Model']. '<br>';
echo 'BodyClass: '. $data['BodyClass']. '<br>';
echo 'Doors: '. $data['Doors']. '<br>';
echo 'Series: '. $data['Series']. '<br>';
echo 'VehicleType: '. $data['VehicleType']. '<br>';
You could also build your desired data array manually with only keys and blank values then allow your foreach to populate it. Then you could use another forech to print your data array as it will be in your desired order.
Just a suggestion. Hope it helps you get a little further in your process.