使用 PHP 解析 YAML 文件不会将操作数组转储为正确的 YAML 格式
Parsing YAML file with PHP does not dump manipulated array back into correct YAML format
我制作了一个程序,使用 yaml_parse_file()
将 YAML 文件加载到 PHP 数组中,然后我使用此函数操作数组:
function removeElementWithValue($array, $key, $value){
foreach($array as $subKey => $subArray){
if($subArray[$key] == $value){
unset($array[$subKey]);
}
}
return $array;
}
然后我尝试使用 yaml_emit()
将新数组转储回 YAML 文件
问题在于:程序没有使用正确的 YAML 格式将数组转储到 YAML 文件中。只有当我的函数只删除数组中的最后一个元素时,它才会将数组转储为正确的 YAML 格式。如果我使用该函数从数组中删除任何其他元素,它将转储回 YAML 文件,如:
---
1:
ID: 1
startX: 258.000000
endX: 276.000000
startZ: 271.000000
endZ: 290.000000
price: 38000.000000
owner: KeithDavisRatio
level: world
invitee: []
expires: ~
...
什么时候应该像
那样转储
- ID: 1
startX: 258.000000
endX: 276.000000
startZ: 271.000000
endZ: 290.000000
price: 38000.000000
owner: KeithDavisRatio
level: world
invitee: []
expires: ~
...
问题:如何正确操作数组,以便 yaml_emit()
将新数组转储到具有正确 YAML 格式的文件中?预先感谢您的帮助。
完整节目:
#Loads Land.yml into PHP Array
$file = '/Users/keithdavis/MineCraft/pocketmine-mp/plugins/EconomyLand/Land.yml';
$array = yaml_parse_file($file);
echo "Loaded into PHP: \n";
print_r($array);
echo "Would you like to
\n1: Delete all land claims by owner?
\n2: Delete all land claims except owner?\n";
$answer = readline("\nType 1 or 2: ");
#Answer 1
if ($answer == 1){
$ownerName = readline("What is the owner's name?: ");
#Searches land array for owner
if(array_search($ownerName, array_column($array, 'owner')) !== false ){
echo "...Found $ownerName \n";
#Removes owner from array
$array = removeElementWithValue($array, 'owner', $ownerName);
echo "...Removed claims owned by $ownerName \n";
#Sends data back to Land.yml
$landAfterDump = yaml_emit($array);
file_put_contents($file, $landAfterDump);
echo "YAML Data dumped back: \n";
echo $landAfterDump;
}else{
echo 'Did not find ' . $ownerName . "\n";
}
#Answer 2
}elseif ($answer == 2){
$ownerName = readline("What is the owner's name?: ");
#Searches land array for owner
if(array_search($ownerName, array_column($array, 'owner')) !== false ){
echo "...Found claims by $ownerName \n";
#Removes from array except owner
$array = removeElementWithValueExcept($array, 'owner', $ownerName);
echo "...Removed claims not owned by $ownerName \n";
#Sends data back to Land.yml
$landAfterDump = yaml_emit($array);
file_put_contents($file, $landAfterDump);
echo "YAML Data dumped back: \n";
echo $landAfterDump;
}
else {
echo 'Did not find ' . $ownerName . "\n";
}
}else {
echo "Input not recognized. Please run program again.\n";
}
#Remove from array
function removeElementWithValue($array, $key, $value){
foreach($array as $subKey => $subArray){
if($subArray[$key] == $value){
unset($array[$subKey]);
}
}
return $array;
}
#Remove from array except
function removeElementWithValueExcept($array, $key, $value){
foreach($array as $subKey => $subArray){
if($subArray[$key] !== $value){
unset($array[$subKey]);
}
}
return $array;
} <?php
#Loads Land.yml into PHP Array
$file = '/Users/keithdavis/MineCraft/pocketmine-mp/plugins/EconomyLand/Land.yml';
$array = yaml_parse_file($file);
echo "Loaded into PHP: \n";
print_r($array);
echo "Would you like to
\n1: Delete all land claims by owner?
\n2: Delete all land claims except owner?\n";
$answer = readline("\nType 1 or 2: ");
#Answer 1
if ($answer == 1){
$ownerName = readline("What is the owner's name?: ");
#Searches land array for owner
if(array_search($ownerName, array_column($array, 'owner')) !== false ){
echo "...Found $ownerName \n";
#Removes owner from array
$array = removeElementWithValue($array, 'owner', $ownerName);
echo "...Removed claims owned by $ownerName \n";
#Sends data back to Land.yml
$landAfterDump = yaml_emit($array);
file_put_contents($file, $landAfterDump);
echo "YAML Data dumped back: \n";
echo $landAfterDump;
}else{
echo 'Did not find ' . $ownerName . "\n";
}
#Answer 2
}elseif ($answer == 2){
$ownerName = readline("What is the owner's name?: ");
#Searches land array for owner
if(array_search($ownerName, array_column($array, 'owner')) !== false ){
echo "...Found claims by $ownerName \n";
#Removes from array except owner
$array = removeElementWithValueExcept($array, 'owner', $ownerName);
echo "...Removed claims not owned by $ownerName \n";
#Sends data back to Land.yml
$landAfterDump = yaml_emit($array);
file_put_contents($file, $landAfterDump);
echo "YAML Data dumped back: \n";
echo $landAfterDump;
}
else {
echo 'Did not find ' . $ownerName . "\n";
}
}else {
echo "Input not recognized. Please run program again.\n";
}
#Remove from array
function removeElementWithValue($array, $key, $value){
foreach($array as $subKey => $subArray){
if($subArray[$key] == $value){
unset($array[$subKey]);
}
}
return $array;
}
#Remove from array except
function removeElementWithValueExcept($array, $key, $value){
foreach($array as $subKey => $subArray){
if($subArray[$key] !== $value){
unset($array[$subKey]);
}
}
return $array;
}
Land.yml 文件:
---
- ID: 0
startX: 260.000000
endX: 276.000000
startZ: 244.000000
endZ: 256.000000
price: 22100.000000
owner: BlockBach
level: world
invitee: []
expires: ~
- ID: 1
startX: 258.000000
endX: 276.000000
startZ: 271.000000
endZ: 290.000000
price: 38000.000000
owner: KeithDavisRatio
level: world
invitee: []
expires: ~
- ID: 2
startX: 353.000000
endX: 364.000000
startZ: 218.000000
endZ: 253.000000
price: 43200.000000
owner: TestDummy1
level: world
invitee: []
expires: ~
- ID: 3
startX: 317.000000
endX: 336.000000
startZ: 302.000000
endZ: 314.000000
price: 26000.000000
owner: TestDummy1
level: world
invitee: []
expires: ~
- ID: 4
startX: 203.000000
endX: 223.000000
startZ: 312.000000
endZ: 352.000000
price: 86100.000000
owner: Elytra1
level: world
invitee: []
expires: ~
- ID: 5
startX: 157.000000
endX: 174.000000
startZ: 318.000000
endZ: 334.000000
price: 30600.000000
owner: Elytra1
level: world
invitee: []
expires: ~
- ID: 6
startX: 121.000000
endX: 128.000000
startZ: 286.000000
endZ: 299.000000
price: 11200.000000
owner: Elytra1
level: world
invitee: []
expires: ~
- ID: 7
startX: 226.000000
endX: 244.000000
startZ: 214.000000
endZ: 225.000000
price: 22800.000000
owner: Haxley
level: world
invitee: []
expires: ~
- ID: 8
startX: 193.000000
endX: 222.000000
startZ: 141.000000
endZ: 172.000000
price: 96000.000000
owner: Haxley
level: world
invitee: []
expires: ~
- ID: 9
startX: 171.000000
endX: 199.000000
startZ: 45.000000
endZ: 80.000000
price: 104400.000000
owner: Haxley
level: world
invitee: []
expires: ~
...
当您修改数组时,您是在删除元素而不重新编制索引。然后 yaml_emit
得到一个缺少键的数组,所以它会尝试制作那种奇怪的语法。我不知道这是库中的错误还是所需的行为。
要获得所需的输出,请更改以下行(出现 2 次):
// Before
$landAfterDump = yaml_emit($array);
// After
$landAfterDump = yaml_emit(array_values($array));
我制作了一个程序,使用 yaml_parse_file()
将 YAML 文件加载到 PHP 数组中,然后我使用此函数操作数组:
function removeElementWithValue($array, $key, $value){
foreach($array as $subKey => $subArray){
if($subArray[$key] == $value){
unset($array[$subKey]);
}
}
return $array;
}
然后我尝试使用 yaml_emit()
问题在于:程序没有使用正确的 YAML 格式将数组转储到 YAML 文件中。只有当我的函数只删除数组中的最后一个元素时,它才会将数组转储为正确的 YAML 格式。如果我使用该函数从数组中删除任何其他元素,它将转储回 YAML 文件,如:
---
1:
ID: 1
startX: 258.000000
endX: 276.000000
startZ: 271.000000
endZ: 290.000000
price: 38000.000000
owner: KeithDavisRatio
level: world
invitee: []
expires: ~
...
什么时候应该像
那样转储- ID: 1
startX: 258.000000
endX: 276.000000
startZ: 271.000000
endZ: 290.000000
price: 38000.000000
owner: KeithDavisRatio
level: world
invitee: []
expires: ~
...
问题:如何正确操作数组,以便 yaml_emit()
将新数组转储到具有正确 YAML 格式的文件中?预先感谢您的帮助。
完整节目:
#Loads Land.yml into PHP Array
$file = '/Users/keithdavis/MineCraft/pocketmine-mp/plugins/EconomyLand/Land.yml';
$array = yaml_parse_file($file);
echo "Loaded into PHP: \n";
print_r($array);
echo "Would you like to
\n1: Delete all land claims by owner?
\n2: Delete all land claims except owner?\n";
$answer = readline("\nType 1 or 2: ");
#Answer 1
if ($answer == 1){
$ownerName = readline("What is the owner's name?: ");
#Searches land array for owner
if(array_search($ownerName, array_column($array, 'owner')) !== false ){
echo "...Found $ownerName \n";
#Removes owner from array
$array = removeElementWithValue($array, 'owner', $ownerName);
echo "...Removed claims owned by $ownerName \n";
#Sends data back to Land.yml
$landAfterDump = yaml_emit($array);
file_put_contents($file, $landAfterDump);
echo "YAML Data dumped back: \n";
echo $landAfterDump;
}else{
echo 'Did not find ' . $ownerName . "\n";
}
#Answer 2
}elseif ($answer == 2){
$ownerName = readline("What is the owner's name?: ");
#Searches land array for owner
if(array_search($ownerName, array_column($array, 'owner')) !== false ){
echo "...Found claims by $ownerName \n";
#Removes from array except owner
$array = removeElementWithValueExcept($array, 'owner', $ownerName);
echo "...Removed claims not owned by $ownerName \n";
#Sends data back to Land.yml
$landAfterDump = yaml_emit($array);
file_put_contents($file, $landAfterDump);
echo "YAML Data dumped back: \n";
echo $landAfterDump;
}
else {
echo 'Did not find ' . $ownerName . "\n";
}
}else {
echo "Input not recognized. Please run program again.\n";
}
#Remove from array
function removeElementWithValue($array, $key, $value){
foreach($array as $subKey => $subArray){
if($subArray[$key] == $value){
unset($array[$subKey]);
}
}
return $array;
}
#Remove from array except
function removeElementWithValueExcept($array, $key, $value){
foreach($array as $subKey => $subArray){
if($subArray[$key] !== $value){
unset($array[$subKey]);
}
}
return $array;
} <?php
#Loads Land.yml into PHP Array
$file = '/Users/keithdavis/MineCraft/pocketmine-mp/plugins/EconomyLand/Land.yml';
$array = yaml_parse_file($file);
echo "Loaded into PHP: \n";
print_r($array);
echo "Would you like to
\n1: Delete all land claims by owner?
\n2: Delete all land claims except owner?\n";
$answer = readline("\nType 1 or 2: ");
#Answer 1
if ($answer == 1){
$ownerName = readline("What is the owner's name?: ");
#Searches land array for owner
if(array_search($ownerName, array_column($array, 'owner')) !== false ){
echo "...Found $ownerName \n";
#Removes owner from array
$array = removeElementWithValue($array, 'owner', $ownerName);
echo "...Removed claims owned by $ownerName \n";
#Sends data back to Land.yml
$landAfterDump = yaml_emit($array);
file_put_contents($file, $landAfterDump);
echo "YAML Data dumped back: \n";
echo $landAfterDump;
}else{
echo 'Did not find ' . $ownerName . "\n";
}
#Answer 2
}elseif ($answer == 2){
$ownerName = readline("What is the owner's name?: ");
#Searches land array for owner
if(array_search($ownerName, array_column($array, 'owner')) !== false ){
echo "...Found claims by $ownerName \n";
#Removes from array except owner
$array = removeElementWithValueExcept($array, 'owner', $ownerName);
echo "...Removed claims not owned by $ownerName \n";
#Sends data back to Land.yml
$landAfterDump = yaml_emit($array);
file_put_contents($file, $landAfterDump);
echo "YAML Data dumped back: \n";
echo $landAfterDump;
}
else {
echo 'Did not find ' . $ownerName . "\n";
}
}else {
echo "Input not recognized. Please run program again.\n";
}
#Remove from array
function removeElementWithValue($array, $key, $value){
foreach($array as $subKey => $subArray){
if($subArray[$key] == $value){
unset($array[$subKey]);
}
}
return $array;
}
#Remove from array except
function removeElementWithValueExcept($array, $key, $value){
foreach($array as $subKey => $subArray){
if($subArray[$key] !== $value){
unset($array[$subKey]);
}
}
return $array;
}
Land.yml 文件:
---
- ID: 0
startX: 260.000000
endX: 276.000000
startZ: 244.000000
endZ: 256.000000
price: 22100.000000
owner: BlockBach
level: world
invitee: []
expires: ~
- ID: 1
startX: 258.000000
endX: 276.000000
startZ: 271.000000
endZ: 290.000000
price: 38000.000000
owner: KeithDavisRatio
level: world
invitee: []
expires: ~
- ID: 2
startX: 353.000000
endX: 364.000000
startZ: 218.000000
endZ: 253.000000
price: 43200.000000
owner: TestDummy1
level: world
invitee: []
expires: ~
- ID: 3
startX: 317.000000
endX: 336.000000
startZ: 302.000000
endZ: 314.000000
price: 26000.000000
owner: TestDummy1
level: world
invitee: []
expires: ~
- ID: 4
startX: 203.000000
endX: 223.000000
startZ: 312.000000
endZ: 352.000000
price: 86100.000000
owner: Elytra1
level: world
invitee: []
expires: ~
- ID: 5
startX: 157.000000
endX: 174.000000
startZ: 318.000000
endZ: 334.000000
price: 30600.000000
owner: Elytra1
level: world
invitee: []
expires: ~
- ID: 6
startX: 121.000000
endX: 128.000000
startZ: 286.000000
endZ: 299.000000
price: 11200.000000
owner: Elytra1
level: world
invitee: []
expires: ~
- ID: 7
startX: 226.000000
endX: 244.000000
startZ: 214.000000
endZ: 225.000000
price: 22800.000000
owner: Haxley
level: world
invitee: []
expires: ~
- ID: 8
startX: 193.000000
endX: 222.000000
startZ: 141.000000
endZ: 172.000000
price: 96000.000000
owner: Haxley
level: world
invitee: []
expires: ~
- ID: 9
startX: 171.000000
endX: 199.000000
startZ: 45.000000
endZ: 80.000000
price: 104400.000000
owner: Haxley
level: world
invitee: []
expires: ~
...
当您修改数组时,您是在删除元素而不重新编制索引。然后 yaml_emit
得到一个缺少键的数组,所以它会尝试制作那种奇怪的语法。我不知道这是库中的错误还是所需的行为。
要获得所需的输出,请更改以下行(出现 2 次):
// Before
$landAfterDump = yaml_emit($array);
// After
$landAfterDump = yaml_emit(array_values($array));