I have a text file that stores information about different items.
This file is structured. Each item in the file is separated by curly braces { } and proceded with a comma. Each item has a list of attributes it has, and attributes can be there or not be there. If they're not there, the server assumes they're "default".
Each entry is surrounded by curly braces and ends with a comma: { }, The file also includes standard C commenting, // along with /* */ Each attribute of the item is standardized from a pool of 33 attributes, only 3 of which are mandatory. Attributes can be included or left out. Attributes that are not included are assumed to be default from the backend program. There are a few attributes that can be multi line or even multi attribute (forming an array, if you will).
So, the file roughly looks like this:
itemdb: (
/*
{
Multi line comment
here to explain the file
},
*/
// Here starts the items
{
Id: 500
DatabaseName: "Item_1"
Name: "Item 1"
Type: 1
Buy: 40
Weight: 10
},
{
Id: 501
DatabaseName: "Item_2"
Name: "Item 2"
Type: 1
Sell: 600
Weight: 200
Script: <" do stuff; ">
},
// Here is some more items
{
Id: 637
DatabaseName: "Item_137"
Name: "Item 137"
Type: 5
Buy: 9000
Weight: 300
Trade: {
nodrop: true
notrade: true
}
Script: <"
do this stuff;
then this stuff;
">
},
// Note: Edited this in 2015-11-23, see below.
)
I need a way to Break all elements into an array for display to the user. The array would look something like this (from the example above):
$itemDB = Array
(
[500] => Array
(
[DatabaseName] => Item_1
[Name] => Item 1
[Type] => 1
[Buy] => 40
[Weight] => 10
)
[501] => Array
(
[DatabaseName] => Item_2
[Name] => Item 2
[Type] => 1
[Sell] => 600
[Weight] => 200
[Script] => do stuff
)
[637] => Array
(
[DatabaseName] => Item_137
[Name] => Item 137
[Type] => 5
[Buy] => 9000
[Weight] => 300
[Trade] => array
(
[nodrop] => true
[notrade] => true
)
[Script] => do this stuff;\nthen this stuff
)
);
( so basically break the file into a multidimensional array with the 'Id' attribute of the file being the key of each array and each attribute of the file being its own key/value )
I do manage to come up with the following code to break the array into each entry:
$ready = str_replace(array("{","}"),"|", $itemDB);
$itemDB_explode = explode("|", $ready);
This code however only gets me halfway there. I basically come out with an array like this:
[7]=> string(124) " Id: 501 DatabaseName: "Item_2" Name: "Item 2" Type: 1 Sell: 600 Weight: 200 Script: <" do stuff "> "
But for the life of me I can't figure out how to get it any farther than this, including how to make the key of the array the Id and each attribute its own key/value.
the point is to display the entry to the user, allow them to make edits and then save the file back. Hopefully I can get assistance with saving it back as well.
for those that will undoubtedly ask: Yes, I know something like this is better suited for a SQL database. Problem being that this file and the backend to read and interpret it is not written by me and I have no way of changing it. I'm merely writing the web based front end to easily change that file.
Thank you in advance for help you can provide.
Edit 2015-11-23: I left some attributes off of my original question. Consider this edit to the actual file with those missing attributes added:
{
Id: 845
DatabaseName: "Item_345"
Name: "Item 345"
Type: 3
Buy: 30000
Nouse: {
override: 30
sitting: true
}
Stack: [99, 4]
OnEquipScript: <" do this stuff; ">
OnUnequipScript: <"
do some more stuff;
this is some more stuff;
">
},
Consider what the resulting array would look like for that additional block in the file:
[845] => Array
(
[DatabaseName] => Item_345
[Name] => Item 345
[Type] => 3
[Buy] => 30000
[Nouse] => array
(
[override] => 30
[sitting] => true
)
[Stack] =>
(
[0] => 99
[1] => 4
)
[OnEquipScript] => do this stuff;
[OnUnequipScript] => do some more stuff;\nthis is some more stuff;
)
Thought I could knock this off in 15 minutes while I sat on hold, but the multi-line script stuck me at the end. So it took 35 minutes instead, but I can assure you, you weren't halfway there ;)
<?php
$items = array();
$in_comment = false;
$in_trade = false;
$in_script = false;
$itemDB = file("foo.txt");
foreach ($itemDB as $row) {
$row = trim($row);
if (strpos($row, "//") === 0) continue;
if (strpos($row, "/*") === 0) {
$in_comment = true;
continue;
}
if (strpos($row, "*/") === 0) {
$in_comment = false;
continue;
}
if ($in_comment) continue;
if ($row === "itemdb: (") continue;
if ($row === ")") continue;
if (strpos($row, "{") === 0) {
$item = array();
}
elseif (!$in_trade && strpos($row, "}") === 0) {
$items[$item["Id"]] = $item;
} else {
$row = explode(":", $row);
$key = trim($row[0]);
$val = isset($row[1]) ? trim($row[1]) : "";
if ($key === "Trade" && strpos($val, "{") === 0) {
$in_trade = true;
$item["Trade"] = array();
continue;
} elseif ($in_trade && $key === "}") {
$in_trade = false;
continue;
} elseif ($key === "Script") {
$in_script = true;
$item["Script"] = "";
}
if ($in_trade) {
$item["Trade"][$key] = $val;
} elseif ($in_script) {
$item["Script"] .= (empty($val) ? $key : $val) . "\n";
if (strpos($key, "\">") !== false || strpos($val, "\">") !== false) {
$item["Script"] = str_replace(array("<\"", "\">"), "", $item["Script"]);
$item["Script"] = trim($item["Script"]);
$in_script = false;
}
} else {
$item[$key] = $val;
}
}
}
print_r($items);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With