PHP 7.2 - SQL Server 2017 - 创建嵌套数组响应
PHP 7.2 - SQL Server 2017 - Create Nested Array response
我有一个从 SQL 服务器数据库检索数据的存储过程。
根据查询结果,我需要填充 SOAPClient 方法的参数数组
目前我正在手动创建数组,但我想知道是否有可能(并且值得)以 SOAP 方法要求的方式直接从 TSQL:
使用 PHP 7.2 - SQL 服务器 2017
我举个例子说明一下:
这是我的查询结果:
Array
(
[Key] => R******l
[Password] => c*************z
[AccountNumber] => 0****1
[MeterNumber] => 2******5
[ShipTimestamp] => 2020-10-29T10:24:19+01:00
[ServiceType] => INTERNATIONAL_ECONOMY
[PackagingType] => YOUR_PACKAGING
[PreferredCurrency] => EUR
[Weight_Units] => KG
[TotalWeight] => 0.02
...
)
虽然它应该 return 像这样:
Array
(
[Authentication] => Array
(
[User] => Array
(
[Key] => R******l
[Password] => c*************z
)
)
[Client] => Array
(
[Account] => 0*******1
[Meter] => 2*******5
)
[Shipment] => Array
(
[ShipTimestamp] => 2020-10-29T10:41:26+01:00
[DropoffType] => REGULAR_PICKUP
[ServiceType] => INTERNATIONAL_ECONOMY
[PackagingType] => YOUR_PACKAGING
[PreferredCurrency] => EUR
[TotalWeight] => Array
(
[Units] => KG
[Value] => 0.02
)
)
...
)
是否可行且值得?
你可以 return 一行一 JSON 列使用 FOR JSON PATH
1 in SQL and in PHP json_decode($json, true)
3 和 $assoc
参数设置为 true
以将 JSON 解码为数组。
SELECT (
SELECT user_key [Authentication.User.Key]
, user_password [Authentication.User.Password]
, client_account [Client.Account]
, client_meter [Client.Meter]
--- and so on
FROM my_table
FOR JSON PATH
) [json]
结果应该是JSON
{
"Authentication": { "User": { "Key": "XXX", "Password": "XXX" } },
"Client": { "Account": "YYY", "Meter": 200500 }
}
现在您可以在 PHP 中获取该值,对其进行解码并提供给 SOAP。
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
$json = json_decode($row['json'], true);
但在 SQL 中,您需要一种特殊的语法来格式化这些类型:
- 日期 值
CONVERT(varchar(10), date_col, 120)
-
120
得到 2020-10-29 11:32:00
格式,varchar(10)
trim 只是日期部分,varchar(20)
得到整个日期+时间2
- 布尔值 值
CAST(boolean_col as bit)
(0 -> false
, 1 -> true
)
更多信息:
举个例子,这也可以通过映射来完成。
数据定义为
$data = [
'Key' => 'R******l',
'Password' => 'c*************z',
'AccountNumber' => '0****1',
'MeterNumber' => '2******5',
'ShipTimestamp' => '2020-10-29T10:24:19+01:00',
'ServiceType' => 'INTERNATIONAL_ECONOMY',
'PackagingType' => 'YOUR_PACKAGING',
'PreferredCurrency' => 'EUR',
'Weight_Units' => 'KG',
'TotalWeight' => '0.02',
];
用散列定义的映射 table。名字可改,群可加深。
$mapping = [
'Key' => ['name' => 'Key', 'group' => ['Authentication', 'User']],
'Password' => ['name' => 'Password', 'group' => ['Authentication', 'User']],
'AccountNumber' => ['name' => 'Account', 'group' => ['Client']],
'MeterNumber' => ['name' => 'Meter', 'group' => ['Client']],
'ShipTimestamp' => ['name' => 'ShipTimestamp', 'group' => ['Shipment']],
'ServiceType' => ['name' => 'ServiceType', 'group' => ['Shipment']],
'PackagingType' => ['name' => 'PackagingType', 'group' => ['Shipment']],
'PreferredCurrency' => ['name' => 'PreferredCurrency', 'group' => ['Shipment']],
'Weight_Units' => ['name' => 'Units', 'group' => ['Shipment', 'TotalWeight']],
'TotalWeight' => ['name' => 'Value', 'group' => ['Shipment', 'TotalWeight']],
];
现在是一个简单的例程,通过映射 table 重新映射数据并放入 $mappedData
。
$mappedData = [];
foreach($data as $key => $value) {
$map = $mapping[$key];
$root = array_shift($map['group']);
krsort($map['group']);
$value = [$map['name'] => $value];
foreach($map['group'] as $group) {
$value = [$group => $value];
}
$new[$root] = $value;
$mappedData = array_replace_recursive ($mappedData, $new);
}
执行时看起来像这样
Array
(
[Authentication] => Array
(
[User] => Array
(
[Key] => R******l
[Password] => c*************z
)
)
[Client] => Array
(
[Account] => 0****1
[Meter] => 2******5
)
[Shipment] => Array
(
[ShipTimestamp] => 2020-10-29T10:24:19+01:00
[ServiceType] => INTERNATIONAL_ECONOMY
[PackagingType] => YOUR_PACKAGING
[PreferredCurrency] => EUR
[TotalWeight] => Array
(
[Units] => KG
[Value] => 0.02
)
)
)
我有一个从 SQL 服务器数据库检索数据的存储过程。
根据查询结果,我需要填充 SOAPClient 方法的参数数组
目前我正在手动创建数组,但我想知道是否有可能(并且值得)以 SOAP 方法要求的方式直接从 TSQL:
使用 PHP 7.2 - SQL 服务器 2017
我举个例子说明一下: 这是我的查询结果:
Array
(
[Key] => R******l
[Password] => c*************z
[AccountNumber] => 0****1
[MeterNumber] => 2******5
[ShipTimestamp] => 2020-10-29T10:24:19+01:00
[ServiceType] => INTERNATIONAL_ECONOMY
[PackagingType] => YOUR_PACKAGING
[PreferredCurrency] => EUR
[Weight_Units] => KG
[TotalWeight] => 0.02
...
)
虽然它应该 return 像这样:
Array
(
[Authentication] => Array
(
[User] => Array
(
[Key] => R******l
[Password] => c*************z
)
)
[Client] => Array
(
[Account] => 0*******1
[Meter] => 2*******5
)
[Shipment] => Array
(
[ShipTimestamp] => 2020-10-29T10:41:26+01:00
[DropoffType] => REGULAR_PICKUP
[ServiceType] => INTERNATIONAL_ECONOMY
[PackagingType] => YOUR_PACKAGING
[PreferredCurrency] => EUR
[TotalWeight] => Array
(
[Units] => KG
[Value] => 0.02
)
)
...
)
是否可行且值得?
你可以 return 一行一 JSON 列使用 FOR JSON PATH
1 in SQL and in PHP json_decode($json, true)
3 和 $assoc
参数设置为 true
以将 JSON 解码为数组。
SELECT (
SELECT user_key [Authentication.User.Key]
, user_password [Authentication.User.Password]
, client_account [Client.Account]
, client_meter [Client.Meter]
--- and so on
FROM my_table
FOR JSON PATH
) [json]
结果应该是JSON
{
"Authentication": { "User": { "Key": "XXX", "Password": "XXX" } },
"Client": { "Account": "YYY", "Meter": 200500 }
}
现在您可以在 PHP 中获取该值,对其进行解码并提供给 SOAP。
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
$json = json_decode($row['json'], true);
但在 SQL 中,您需要一种特殊的语法来格式化这些类型:
- 日期 值
CONVERT(varchar(10), date_col, 120)
-120
得到2020-10-29 11:32:00
格式,varchar(10)
trim 只是日期部分,varchar(20)
得到整个日期+时间2 - 布尔值 值
CAST(boolean_col as bit)
(0 -> false
,1 -> true
)
更多信息:
举个例子,这也可以通过映射来完成。
数据定义为
$data = [
'Key' => 'R******l',
'Password' => 'c*************z',
'AccountNumber' => '0****1',
'MeterNumber' => '2******5',
'ShipTimestamp' => '2020-10-29T10:24:19+01:00',
'ServiceType' => 'INTERNATIONAL_ECONOMY',
'PackagingType' => 'YOUR_PACKAGING',
'PreferredCurrency' => 'EUR',
'Weight_Units' => 'KG',
'TotalWeight' => '0.02',
];
用散列定义的映射 table。名字可改,群可加深。
$mapping = [
'Key' => ['name' => 'Key', 'group' => ['Authentication', 'User']],
'Password' => ['name' => 'Password', 'group' => ['Authentication', 'User']],
'AccountNumber' => ['name' => 'Account', 'group' => ['Client']],
'MeterNumber' => ['name' => 'Meter', 'group' => ['Client']],
'ShipTimestamp' => ['name' => 'ShipTimestamp', 'group' => ['Shipment']],
'ServiceType' => ['name' => 'ServiceType', 'group' => ['Shipment']],
'PackagingType' => ['name' => 'PackagingType', 'group' => ['Shipment']],
'PreferredCurrency' => ['name' => 'PreferredCurrency', 'group' => ['Shipment']],
'Weight_Units' => ['name' => 'Units', 'group' => ['Shipment', 'TotalWeight']],
'TotalWeight' => ['name' => 'Value', 'group' => ['Shipment', 'TotalWeight']],
];
现在是一个简单的例程,通过映射 table 重新映射数据并放入 $mappedData
。
$mappedData = [];
foreach($data as $key => $value) {
$map = $mapping[$key];
$root = array_shift($map['group']);
krsort($map['group']);
$value = [$map['name'] => $value];
foreach($map['group'] as $group) {
$value = [$group => $value];
}
$new[$root] = $value;
$mappedData = array_replace_recursive ($mappedData, $new);
}
执行时看起来像这样
Array
(
[Authentication] => Array
(
[User] => Array
(
[Key] => R******l
[Password] => c*************z
)
)
[Client] => Array
(
[Account] => 0****1
[Meter] => 2******5
)
[Shipment] => Array
(
[ShipTimestamp] => 2020-10-29T10:24:19+01:00
[ServiceType] => INTERNATIONAL_ECONOMY
[PackagingType] => YOUR_PACKAGING
[PreferredCurrency] => EUR
[TotalWeight] => Array
(
[Units] => KG
[Value] => 0.02
)
)
)