Ограничение и упорядочение значений в массиве

Используя некоторый код из API NHTSA, мой собственный и идеи с этого сайта, оборачивая его в функцию, он работает просто отлично, но не будет работать на моем живом сервере.

На живом сервере он выдавал ошибку, которую я наконец-то решил в коде, используя ярлык массива, не поддерживаемый версией PHP моего живого сервера:

Ошибка разбора: синтаксическая ошибка, неожиданный ‘[‘, ожидающий ‘)’ в /home/pchome/public_html/verify/functions/sitefunctions.php в строке 9

что это за строка:

$postdata = http_build_query(["data" => $VINS, "format" => "JSON"]);

Изменено это работает, а также изменил аналогичный код в нескольких других местах таким же образом:

$postdata = http_build_query(array("data" => $VINS, "format" => "JSON"));

Иногда (но не всегда) я могу передать ему несколько VIN-адресов в виде списка через точку с запятой. Этот формат не подлежит изменению, так что же нужно для обеспечения этой функциональности? (Образцы VIN: 3GNDA13D76S000000; 5XYKT3A12CG000000

// Uses NHTSA API to decode VIN(s)
function decodeVINS($VINS) {
if ($VINS) :
$return = "";
$postdata = http_build_query(array("data" => $VINS, "format" => "JSON"));
$stream_options = array(
'http' => array(
'header' => "Content-Type: application/x-www-form-urlencoded\r\n".
"Content-Length: ".strlen($postdata)."\r\n",
'method' => "POST",
'content' => $postdata
)
);
$context = stream_context_create($stream_options);
$apiURL = "https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVINValuesBatch/";

$fp = @fopen($apiURL, 'rb', FALSE, $context);
$results = array_column(json_decode(@stream_get_contents($fp),TRUE), '0');
$results = $results[0];

$output = "<blockquote>\n";
$output .= "<div><strong>VIN: {$results['VIN']}</strong></div>\n";
$output .= "<div><strong>ErrorCode: {$results['ErrorCode']}</strong></div>\n";

if ($results['AdditionalErrorText']) :
$output .= "<div><strong>AdditionalErrorText: {$results['AdditionalErrorText']}</strong></div>\n";
endif;

foreach ($results as $key => $val) :
if ($val && $key != "VIN" && $key != "ErrorCode" && $key != "AdditionalErrorText") :
$output .= "<div>$key: $val</div>";
endif;
endforeach;

$output .= "</blockquote>\n\n";
else :
$output = "Enter VINs above separated by line breaks";
endif;

return $output;
}

. . . и это выводит что-то вроде этого:

VIN: JB7FJ43S5KJ000911
ErrorCode: 0 - VIN decoded clean. Check Digit (9th position) is correct
BodyClass: Sport Utility Vehicle (SUV)/Multi Purpose Vehicle (MPV)
DisplacementCC: 3000
DisplacementCI: 183.0712322841
DisplacementL: 3
DriveType: 4WD/4-Wheel Drive/4x4
EngineConfiguration: V-Shaped
EngineCylinders: 6
FuelTypePrimary: Gasoline
GVWR: Class 1C: 4,001 - 5,000 lb (1,814 - 2,268 kg)
Make: DODGE
Manufacturer: MITSUBISHI MOTORS CORPORATION (MMC)
ManufacturerId: 1052
Model: Raider
ModelYear: 1989
PlantCity: Nagoya
PlantCompanyName: Nagoya #3
PlantCountry: Japan
VehicleType: TRUCK

0

Решение

Работа с JSON вместо CSV, на мой взгляд, будет намного проще / прямой / стабильной.

Я добавил параметр ($fields) к вызову пользовательской функции, которая будет определять, как изолировать и отсортировать ваши данные.

Я также изменил первый параметр ($VINs), для передачи в виде массива вместо строки, разделенной точкой с запятой. Это, я надеюсь, упрощает вашу обработку — если это не так, вы можете вернуться к исходному формату строки и удалить мой implode(";",$VINs) вызов.

Код: (демонстрация)

function searchByVINs ($VINs,$fields) {
// test multi-VIN batching via textarea at bottom of https://vpic.nhtsa.dot.gov/api/
$stream_options_content = http_build_query(["data" => implode(";", $VINS), "format" => "JSON"]);
$stream_options = [
'http' => [
'header' => "Content-Type: application/x-www-form-urlencoded\r\n".
"Content-Length: ".strlen($postdata)."\r\n",
'method' => "POST",
'content' => $postdata
]
];
$context = stream_context_create($stream_options);
$apiURL = "https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVINValuesBatch/";

if (!$fp = @fopen($apiURL, "rb", FALSE, $context)) {
return ["success" => false, "response" => "Unable to open stream"];
}

if (!$response = stream_get_contents($fp),true)) {
return ["success" => false, "response" => "Unable to receive streamed data"];
}

if(($data = @json_decode($response,true)) === null && json_last_error()!==JSON_ERROR_NONE){
return ["success" => false, "response" => "Unable to parse streamed data"];
}

if (!isset($data["Message"]) || $data["Message"] != "Results returned successfully") {
return ["success" => false, "response" => "Received unsuccessful dataset"];
}

$return = [];
$keys = array_flip($fields);
foreach ($data["Results"] as $dataset) {
$isolated = array_intersect_key($dataset,$keys);  // only retain the elements with keys that match $fields values
$sorted = array_replace($keys,$isolated);  // order the dataset by order of elements in $fields
$return[] = $sorted;
}

return ["success" => true, "response" => $return];
}


$VINs = ["3GNDA13D76S000000", "5XYKT3A12CG000000"];
$fields = ["VIN", "ModelYear", "Make", "FuelTypePrimary", "DriveType", "BodyClass"];
$response = searchByVINs($VINs,$fields);

if (!$response["success"]) {
echo "Oops, the api call failed. {$response["response"]}";
} else {
foreach ($response["response"] as $item){
echo "<div>";
foreach ($item as $key => $value) {
echo "<div>$key: $value</div>";
}
echo "</div>";
}
}

Выход (из смоделированной демонстрации)

<div>
<div>VIN: 3GNDA13D76S000000</div>
<div>ModelYear: 2006</div>
<div>Make: CHEVROLET</div>
<div>FuelTypePrimary: Gasoline</div>
<div>DriveType: </div>
<div>BodyClass: Wagon</div>
</div>
<div>
<div>VIN: 5XYKT3A12CG000000</div>
<div>ModelYear: 2012</div>
<div>Make: KIA</div>
<div>FuelTypePrimary: Gasoline</div>
<div>DriveType: 4x2</div>
<div>BodyClass: Wagon</div>
</div>
1

Другие решения

Все работает сейчас, так что вот окончательный вариант! При необходимости показывает только строки со значениями и может обрабатывать несколько VIN в одной отправке. Функция вызывается из простой формы, в которой есть текстовое поле для ввода VIN вместе с кнопкой «Отправить».

// Uses NHTSA API to decode VIN(s)
function decodeVINS($VINS) {
// sample VINs 3GNDA13D76S000000;5XYKT3A12CG000000
if ($VINS) :
$postdata = http_build_query(array("data" => $VINS, "format" => "JSON"));
$stream_options = array(
'http' => array(
'header' => "Content-Type: application/x-www-form-urlencoded\r\n".
"Content-Length: ".strlen($postdata)."\r\n",
'method' => "POST",
'content' => $postdata
)
);
$context = stream_context_create($stream_options);
$apiURL = "https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVINValuesBatch/";

$fp = @fopen($apiURL, 'rb', FALSE, $context);
$returnValue = json_decode(@stream_get_contents($fp),TRUE);
if(!isset($returnValue['Results'])):
echo "Invalid return data or no return data. Exiting";
return FALSE;
endif;
$results = $returnValue['Results'];

if(!is_array($results)):
$results = array($results);
endif;

$output = '';
foreach($results as $result):
$output .= "<blockquote>\n";
$output .= "<div><strong>VIN: {$result['VIN']}</strong></div>\n";
$output .= "<div><strong>ErrorCode: {$result['ErrorCode']}</strong></div>\n";

if ($result['AdditionalErrorText']) :
$output .= "<div><strong>AdditionalErrorText: {$result['AdditionalErrorText']}</strong></div>\n";
endif;

foreach ($result as $key => $val) :
if ($val && $key != "VIN" && $key != "ErrorCode" && $key != "AdditionalErrorText") :
$output .= "<div>$key: $val</div>";
endif;
endforeach;
$output .= "</blockquote>\n\n";
endforeach;
else :
$output = "Enter VINs above separated by line breaks";
endif;

return $output;
}
0

По вопросам рекламы [email protected]